/**
 *
 */
 
 
//================================================================
// Node class
//================================================================

/**
 * Constructor.
 */
function Node() {
	this.name = "";
	this.ip = "";
	this.lat = 0.0;
	this.lon = 0.0;
	this.alt = 0.0;
	this.img = "";
	this.type = "";
	this.location = "";
	this.description = "";
	// Fields from dynamic data
	this.status = "";
	// GMarker associated to the node
	this.marker = null;
	
	//
	// Functions
	//
	
	/**
	 * Display the node infos
	 */
	this.displayInfo = function () {
		var point = this.marker.getPoint();
		var html = "<table><tr>";
		if (this.img != "") {
			html += "<td><img src='" + this.img + "'/></td>";
		}
		html += "<td><b>" + this.name + "&nbsp;&nbsp;" + this.description + "</b><br>" + this.location + "<br>";
		html += "Altitude: " + this.alt + "m";
		html += "</td></tr></table>";
		//alert("Html: " + html);
		this.marker.openInfoWindowHtml(html);
	}
	
	/**
	 * Make the node marker in the map
	 */
	this.makeMarker = function () {
		
		var point = new GLatLng(this.lat, this.lon);
		var iconName = "";
		if ((this.status == "OFFLINE") &&
			((this.type == "NODE") || 
			 (this.type == "CLIENT") ||
			 (this.type == "INTERNET"))) {
			iconName = getOfflineIcon();
		} else {
			iconName = getIconByType(this.type);
		}
		var marker = new GMarker(point, icons[iconName]);
		
		this.marker = marker;

		GEvent.bind(marker, "click", this, this.displayInfo);
		//GEvent.addListener(marker, "click", function() {
  		//	alert("(addListener) You clicked a marker.");
		//});
		
		map.addOverlay(marker);		
		
	}
}

//================================================================
// ETX class
//================================================================

/**
 * Constructor.
 */
function ETX(_n1, _n2, _value) {
	this.n1 = _n1;
	this.n2 = _n2;
	this.value = _value;
	
	//alert("etx: " + this.n1.name + "<->" + this.n2.name + " : " + this.value);
	
	//
	// Functions
	//
	
	/**
	 * Display the line for this etx
	 */
	this.makeLine = function () {
		var p1 = new GLatLng(this.n1.lat, this.n1.lon);
		var p2 = new GLatLng(this.n2.lat, this.n2.lon);
		
		var color = this.getLinkColor();
		var width = this.getLinkWidth();
		
		var polyline = new GPolyline([p1, p2], color, width);
		
		map.addOverlay(polyline);

		//alert("Link: " + this.n1.lat + ", " + this.n1.lon + " <-> " + this.n2.lat + ", " + this.n2.lon + " : " + color + " : " + width);
		//alert("Link: " + this.n1.name + " <-> " + this.n2.name + " : " + color + " : " + width);
	}
	
	/**
	 * Compute the link color for this etx
	 */
	this.getLinkColor = function () {
		/*
		if ((this.value > 0.0) && (this.value < 2.0)) {
			return "#00ff00";
		}
		if ((this.value >= 2.0) && (this.value < 5.0)) {
			return "#ffff00";
		}
		if ((this.value >= 5.0) && (this.value < 10.0)) {
			return "#ff0000";
		} else {
			return "#000000";
		}*/
		if (this.value >= 1.00 && this.value < 2.00) return "#000fff"; /* blue */
		else if (this.value >= 2.00 && this.value < 5.00) return "#00d000"; /* green */
		else return "#ffe000"; /* yellow */
	}
	
	/**
	 * Compute the link width for this etx
	 */
	this.getLinkWidth = function () {
		/*
		if ((this.value > 0.0) && (this.value < 2.0)) {
			if ((this.value > 0.0) && (this.value < 1.2)) {
				return 3;
			} else if ((this.value <= 1.2) && (this.value < 1.6)) {
				return 2;
			} else {
				return 1;
			}
		}
		if ((this.value >= 2.0) && (this.value < 5.0)) {
			if ((this.value >= 2.0) && (this.value < 3.0)) {
				return 3;
			} else if ((this.value >= 3.0) && (this.value < 4.0)) {
				return 2;
			} else {
				return 1;
			}
		}
		if ((this.value >= 5.0) && (this.value < 10.0)) {
			if ((this.value >= 5.0) && (this.value < 6.66)) {
				return 3;
			} else if ((this.value >= 6.66) && (this.value < 8.33)) {
				return 2;
			} else {
				return 1;
			}
		} else {
			return 1;
		}*/
		if (this.value >= 1.00 && this.value < 1.20) return 4;
		else if (this.value >= 1.20 && this.value < 1.50) return 2;
		else if (this.value >= 1.50 && this.value < 2.00) return 1;
		else return 2; /* 1 wouldn't be visible enough since green and yellow are quite pale */
										
	}
}

//================================================================
// Common functions
//================================================================

/**
 * Construction des icones pour l'affichage des noeuds
 */
function makeIcons(map) {
	var icon = new GIcon(G_DEFAULT_ICON);
	icon.image = "images/node_online.png";
	icons["ONLINE"] = icon;

	var icon = new GIcon(G_DEFAULT_ICON);
	icon.image = "images/node_offline.png";
	icons["OFFLINE"] = icon;

	var icon = new GIcon(G_DEFAULT_ICON);
	icon.image = "images/node_interest.png";
	icons["INTEREST"] = icon;

	var icon = new GIcon(G_DEFAULT_ICON);
	icon.image = "images/node_construction.png";
	icons["CONSTRUCTION"] = icon;
	
	var icon = new GIcon(G_DEFAULT_ICON);
	icon.image = "images/node_experimentation.png";
	icons["EXPERIMENT"] = icon;

	var icon = new GIcon(G_DEFAULT_ICON);
	icon.image = "images/node_inet.png";
	icons["INTERNET"] = icon;
}

/**
 * Return the icon name from a node type
 */
function getIconByType(nodeType) {
	if (nodeType == "NODE") {
		return "ONLINE";
	} else if (nodeType == "CLIENT") {
		return "EXPERIMENT";
	} else if (nodeType == "PC") {
		return "INTEREST";
	} else if (nodeType == "CONSTRUCTION") {
		return "CONSTRUCTION";
	} else if (nodeType == "INTERNET") {
		return "INTERNET";
	} else {
		return "OFFLINE";
	}
}

/**
 * Return the offline icon
 */
function getOfflineIcon() {
	return "OFFLINE";
}

/**
 * Check the offline nodes
 */
function checkOfflineNodes(xml) {
	var xmlNodes = xml.documentElement.getElementsByTagName("node");
	for (var i = 0; i < xmlNodes.length; i++) {
		var n = xmlNodes.item(i);
		var ip = n.getElementsByTagName("ip")[0].firstChild.nodeValue;
		var status = n.getElementsByTagName("status")[0].firstChild.nodeValue;
		
		var node = nodesByIP[ip];
		if (node != null) {
			node.status = status;
		}
	}
}

/**
 * Read the map center latitude and longitude
 */
function checkMapCenter() {
	var info = map.getCenter();
	//alert("Map center: lat=" + info.lat() + " lng=" + info.lng());
	document.forms['infos'].elements['lat'].value = info.lat();
	document.forms['infos'].elements['lon'].value = info.lng();

}

/**
 * Check if 'ip' is in the ip filter
 */
function checkIPFilter(ip) {
	if (ip.indexOf(ipFilter) == 0) {
		//alert("OK Filter: " + ipFilter + " IP: " + ip);
		return true;
	} else {
		//alert("KO Filter: " + ipFilter + " IP: " + ip);
		return false;
	}
}

/**
 * Check that the ETX between n1 and n2 is alread loaded
 */
function checkETXLoaded(n1, n2) {
	var etx = etxByNodes[n1 + n2];
	if (etx != null) {
		return true;
	}
	return false;
}

/**
 * Load the map and data. 
 * Called from the body.onload event.
 */
function load() {
	if (GBrowserIsCompatible()) {
		map = new GMap2(document.getElementById("map"));
		initMap(map);
		makeIcons(map);
		loadNodesData(map);
	}
}

/**
 * Download the data in node-data.xml and load it on the map. The format we
 * expect is:
 * <data>
 *   <node>
 * 	   <name>N-01</name>
 * 	   <ip>10.0.0.1</ip>
 * 	   <lat>44.1874</lat>
 * 	   <lon>1.74279</lon>
 * 	   <alt>1293</alt>
 * 	   <img>images/nodes/n-01.jpg</img>
 * 	   <type>NODE</type>
 * 	   <location>Here</location>
 * 	   <description>The node here</description>
 * 	 </node>
 * 	 <node>
 * 	 ...
 * </date>
 */
function loadNodes(xml) {
    xmlNodes = xml.documentElement.getElementsByTagName("node");
    //alert("Nb de nodes: " + xmlNodes.length);
    for (var i = 0; i < xmlNodes.length; i++) {
    	var n = xmlNodes.item(i);
    	
        var node = new Node();

		try {
			node.name        = n.getElementsByTagName("name")[0].firstChild.nodeValue;
		} catch (exception) {
			alert("Nodes[" + i + "] hasn't name. Exception: " + exception);
		}
		try {
			node.ip          = n.getElementsByTagName("ip")[0].firstChild.nodeValue;
		} catch (exception) {
			alert("Nodes[" + i + "] hasn't ip. Exception: " + exception);
		}
		try {
			node.lat         = parseFloat(n.getElementsByTagName("lat")[0].firstChild.nodeValue);
		} catch (exception) {
			alert("Nodes[" + i + "] hasn't lat. Exception: " + exception);
		}
		try {
			node.lon         = parseFloat(n.getElementsByTagName("lon")[0].firstChild.nodeValue);
		} catch (exception) {
			alert("Nodes[" + i + "] hasn't lon. Exception: " + exception);
		}
		try {
			node.alt         = parseFloat(n.getElementsByTagName("alt")[0].firstChild.nodeValue);
		} catch (exception) {
			alert("Nodes[" + i + "] hasn't alt. Exception: " + exception);
		}
		try {
			node.img         = n.getElementsByTagName("img")[0].firstChild.nodeValue;
		} catch (exception) {
			//alert("Nodes[" + i + "] hasn't img. Exception: " + exception);
		}
		try {
			node.type        = n.getElementsByTagName("type")[0].firstChild.nodeValue;
		} catch (exception) {
			alert("Nodes[" + i + "] hasn't type. Exception: " + exception);
		}
		try {
			node.location    = n.getElementsByTagName("location")[0].firstChild.nodeValue;
		} catch (exception) {
			alert("Nodes[" + i + "] hasn't location. Exception: " + exception);
		}
		try {
			node.description = n.getElementsByTagName("description")[0].firstChild.nodeValue;
		} catch (exception) {
			alert("Nodes[" + i + "] hasn't description. Exception: " + exception);
		}

        nodes[i] = node;
        nodesByIP[node.ip] = node;
        
    }
}

/**
 * Read the filter value from node-data.xml
 */
function loadFilter(xml) {
	//alert("loadFilter");
	xmlFilters = xml.documentElement.getElementsByTagName("filter");
	var n = xmlFilters.item(0);
	if (n != null) {
		try {
			ipFilter = n.getElementsByTagName("ip")[0].firstChild.nodeValue;
			//alert("IPFilter = " + ipFilter);
		} catch (exception) {
			alert("loadFilter Exception: " + exception);
		}
	} else {
		alert("IPFilter not found !");
	}
}

/**
 * Load the ETX values from the dynamic data
 */
function loadEtx(xml) {
	var xmlEtx = xml.documentElement.getElementsByTagName("etx");
	//alert("Nb de etx: " + xmlEtx.length);
	var j = 0;
	for (var i = 0; i < xmlEtx.length; i++) {
		try {
			var e = xmlEtx.item(i);
			var n1 = e.getElementsByTagName("n1")[0].firstChild.nodeValue;
			var n2 = e.getElementsByTagName("n2")[0].firstChild.nodeValue;
			var value = e.getElementsByTagName("value")[0].firstChild.nodeValue;

			// Check ipfilter
			if ((checkIPFilter(n1)) && (checkIPFilter(n2))) {
			
				var node1 = nodesByIP[n1];
				var node2 = nodesByIP[n2];
	
				if ((node1 == null) || (node2 == null)) {
					//alert("Link detected with an unknown node: " + n1 + " <-> " + n2 + " etx=" + value);
				} else {
					var exist = checkETXLoaded(n2, n1);
					if (exist == false) {
						var etx = new ETX(node1, node2, value);
						etxList[j] = etx;
						j++;
						etxByNodes[n1 + n2] = etx;
					}
				}
			}
		} catch (exception) {
			alert("Exception loading ETX " + i + " : \n" + exception);
		}
	}
}

/**
 * Make the GMap markers for each node
 */
function makeGMarkers() {
	//alert("makeGMarkers: " +  nodes.length);
	for (var i = 0; i < nodes.length; i++) {
		var node = nodes[i];
		node.makeMarker();
	}
	//alert("makeGMarkers: end");
}

/**
 * Make the GMap markers for each node
 */
function makeGMarkersNoConstruction() {
	//alert("makeGMarkers: " +  nodes.length);
	for (var i = 0; i < nodes.length; i++) {
		var node = nodes[i];
		if (node.type != "CONSTRUCTION") {
			node.makeMarker();
		}
	}
	//alert("makeGMarkers: end");
}

/**
 * Make the line in the map for each link
 */
function makeLinks() {
	//alert("makeLinks: " +  etxList.length);
	for (var i = 0; i < etxList.length; i++) {
		var etx = etxList[i];
		if (etx == null) {
			alert("etx[" + i + "] vide !");
		} else {
			etx.makeLine();
		}
	}
	//alert("makeLinks: end");
}

