/*
 Packet Gateway Positions
*/

//globals
var map;
var miniMap;
var icons = new Array();   // map icons
var markers = new Array();  //used to activate marker via sidepanel click
var argCallsign; //assigned if callsign passed as argument - if so, we display popup
var argArray = new Array(); //if more than one callsign specified in the url they are stored here
var minmapscale = 0; 
var maxmapscale = 10; 

//station activity settings
var hoursGreen = 2; //number of hours (or less) for green map symbol
var hoursYellow = 4; //number of hours (or less) for yellow map symbol
//others station markers will be red

var activityHours = 24; //limits the data retrieved from the CMS (hours)

//array and class for storing station information for side panel
var stations = new Array();
function stationData(callsign, html) {
	this.callsign = callsign;
	this.html = html; //table data row for this station
}

//create the google map object
function createMap() {
    map = new GMap2(document.getElementById("map"));
	
    map.addMapType(G_PHYSICAL_MAP);  

    //set min/max map scale 
    var mapTypes = map.getMapTypes(); 
    //overwrite the getMinimumResolution() and getMaximumResolution() methods for each map type 
    for (var i=0; i<mapTypes.length; i++) { 
        mapTypes[i].getMinimumResolution = function() {return minmapscale;} 
        mapTypes[i].getMaximumResolution = function() {return maxmapscale;} 
    } 

	map.addControl(new GLargeMapControl());
	map.addControl(new GMapTypeControl());
	map.addControl(new GScaleControl());
	map.setCenter(new GLatLng(40, -40), 2);
	map.enableDoubleClickZoom();
	
	//create overview map
	miniMap = new GOverviewMapControl(new GSize(150, 150));
    map.addControl(miniMap);

    //update lat/lon on mouse move
    GEvent.addListener(map, "mousemove", function(point){
        document.getElementById("latlon").innerHTML = point.toUrlValue();
    });

    //save map position after each move or zoom change
    GEvent.addListener(map, "dragend", function() {
        saveMapPosition("WinlinkPacketMapPos");
    });
    GEvent.addListener(map, "moveend", function() {
        saveMapPosition("WinlinkPacketMapPos");
    });
    GEvent.addListener(map, "zoomend", function(z_old, z_new) {
        saveMapPosition("WinlinkPacketMapPos");
    });
}

//create icons used on the map
function createIcons() {
    // Create the different icons for the markers
    baseIcon = new GIcon();
    baseIcon.image = "images/markers/mm_20_red.png";
    baseIcon.shadow = "images/markers/mm_20_shadow.png";
    baseIcon.iconSize = new GSize(12, 20);
    baseIcon.shadowSize = new GSize(22, 20);
    baseIcon.iconAnchor = new GPoint(6, 20);
    baseIcon.infoWindowAnchor = new GPoint(5, 10);
    baseIcon.infoShadowAnchor = new GPoint(18, 20);        
    baseIcon.src = "images/markers/mm_20_red.png";
    icons['red'] = baseIcon;
    
    icons['yellow'] = new GIcon(baseIcon);
    icons['yellow'].image = "images/markers/mm_20_yellow.png";
    icons['yellow'].src = 'images/markers/mm_20_yellow.png';
    
    icons['green'] = new GIcon(baseIcon);
    icons['green'].image = "images/markers/mm_20_green.png";
    icons['green'].src = 'images/markers/mm_20_green.png';

    icons['black'] = new GIcon(baseIcon);
    icons['black'].image = "images/markers/mm_20_black.png";
    icons['black'].src = 'images/markers/mm_20_black.png';

    icons['blue'] = new GIcon(baseIcon);
    icons['blue'].image = "images/markers/mm_20_blue.png";
    icons['blue'].src = 'images/markers/mm_20_blue.png';

    icons['brown'] = new GIcon(baseIcon);
    icons['brown'].image = "images/markers/mm_20_brown.png";
    icons['brown'].src = "images/markers/mm_20_brown.png";
    
    icons['white'] = new GIcon(baseIcon);
    icons['white'].image = "images/markers/mm_20_white.png";
    icons['white'].src = "images/markes/mm_20_white.png";

    icons['purple'] = new GIcon(baseIcon);
    icons['purple'].image = "images/markers/mm_20_purple.png";
    icons['purple'].src = "images/markers/mm_20_purple.png";
    
    icons['orange'] = new GIcon(baseIcon);
    icons['orange'].image = "images/markers/mm_20_orange.png";
    icons['orange'].src = "images/markers/mm_20_orange.png";
}

//creates a marker whose tooltip displays the callsign and info window displays station details
function createMarker(point, site) {
	//use different color icons for different levels of activity
	var status = site.getElementsByTagName("HoursSinceStatus");
	if (status[0].firstChild.nodeValue <= hoursGreen) {	 
        markerIcon = icons["green"];
	} else {
		if (status[0].firstChild.nodeValue <= hoursYellow) { 
			markerIcon = icons["yellow"];
		} else {
	        markerIcon = icons["red"];
		}
	}

	var Callsign = getElement(site.getElementsByTagName("Callsign")[0]); 
	var marker = new PdMarker(point, markerIcon);
	marker.setTooltip(Callsign);

    //get raw html (web service provided)
	var html = getElement(site.getElementsByTagName("InfoWindowHtml")[0]);  
	//split into array of title and html
	var tabs = html.split("|");
	//build array of GInfoWindowTab structures
	var infowindowarray = new Array();	
    var i = 0;
    var j = 0;
    while (i < tabs.length-1) {
        infowindowarray[j] = new GInfoWindowTab(tabs[i], tabs[i+1]);
        i++;
        i++;
        j++;
    }

	//show this marker's details in the info window when it is clicked
	GEvent.addListener(marker, "click", function() {
		marker.openInfoWindowTabsHtml(infowindowarray);
		});
	
  return marker;
}

//for sorting station array
function callsignCompare(a, b) {
  if (a.callsign < b.callsign) return -1
  else if (a.callsign > b.callsign) return +1
  else return 0;
}

//called from station header click
function callsignSort() {
	stations.sort(callsignCompare);
	displaySidePanel();
}

//creates content for station list side panel
function displaySidePanel() {
    var infoArea = document.getElementById("sidebar"); 
    var strInfo = '<table>';
	for (var i = 0; i < stations.length; i++) 
		strInfo += stations[i].html;
    infoArea.innerHTML = strInfo + "</table>"; 
};

//called from station list panel to open map info window
function infoOpener(stationKey) {
	GEvent.trigger(markers[stationKey], "click");
}

//search argument list for callsign
function findCallsignInArgs(callsign){
	var x;
	var result = false;
	for (x in argArray) {
		if (argArray[x] == callsign) {
			result = true;
			break;
		}
	}
	return result
}

//use SOAP to make call to web service
function loadStations() {
	showStatus('Loading. Please wait...');
	map.clearOverlays();
	
	//an empty GLatLngBounds object 
	var bounds = new GLatLngBounds();

	//get xml for stations from our web service
	var request = GXmlHttp.create();
	request.open("POST", "../ws/wsStatus.asmx", true);
	request.onreadystatechange = function() {
		if (request.readyState == 4) {
			var xmlDoc = request.responseXML;
			var sites = xmlDoc.documentElement.getElementsByTagName("RMSChannels");
			for (var i = 0; i < sites.length; i++) {
				var Gridsquare = getElement(sites[i].getElementsByTagName("GridSquare")[0]);
				if (Gridsquare == '') continue;
				var lat = getElement(sites[i].getElementsByTagName("Lat")[0]); 
				var lon = getElement(sites[i].getElementsByTagName("Lon")[0]); 
				if ((lat == '') || (lon == '')) continue;
				var status = getElement(sites[i].getElementsByTagName("HoursSinceStatus")[0]);
				var point = new GPoint(parseFloat(lon), parseFloat(lat)); 
				var Callsign = getElement(sites[i].getElementsByTagName("Callsign")[0]); 
				Callsign = Callsign.toUpperCase();
				var Frequency = getElement(sites[i].getElementsByTagName("Frequency")[0]); 
				var stationKey = Callsign + Frequency;
				
				//if more than one callsign specified in arguments, 
				//show only those stations by skipping all others
				if (argArray.length > 1) {
					if (!findCallsignInArgs(Callsign)) continue;
				}
				
				//create the marker
				var marker = createMarker(point, sites[i]);
				markers[stationKey] = marker; //save
				map.addOverlay(marker);
				
                //each time a marker is added, extend the bounds rect to include it
                //if we are displaying a group of specific markers
				if (argArray.length > 1) {
					latlng = new GLatLng(parseFloat(lat), parseFloat(lon));
					if (!bounds.contains(latlng)) {
						bounds.extend(latlng);
					}
				}

				//make callsign clickable (side bar data)
				var clink = '<a href=javascript:infoOpener("' + stationKey + '")>' + Callsign + '</a>';
				var tableRow = '<tr><td>' + clink + '</td></tr>\n';	

				//save station information for later display in the side panel
				stations.push(new stationData(stationKey, tableRow));		
				
				//if a single callsign was passed as argument, show popup info window
				if (argCallsign == Callsign) {
					GEvent.trigger(marker, "click");
				}
			}
			
			//zoom to this group of markers (stations)
			if (argArray.length > 1) {
				//determine the zoom level and center from the bounds rect 
				if (!bounds.isEmpty() && !bounds.isFullLng()) {
					var zoomLevel = map.getBoundsZoomLevel(bounds) - 1;

					//determine the centre from the bounds
					var clat = (bounds.getNorthEast().lat() + bounds.getSouthWest().lat()) /2;
					var clng = (bounds.getNorthEast().lng() + bounds.getSouthWest().lng()) /2;
					
					//adjust the map
					map.setCenter(new GLatLng(clat, clng), zoomLevel);
					//GLog.write('Center: ' + clat + ', ' + clng);
					//GLog.write('Group Zoom Level: ' + zoomLevel);
				}
			}
			//GLog.write('Number of stations: ' + stations.length)
			
			callsignSort();
			showStatus('');
			initLegend();
			loadMapPosition("WinlinkPacketMapPos");
		}
	}
	request.setRequestHeader("Content-Type", "text/xml; charset=utf-8")
	request.setRequestHeader("SOAPAction", "http://www.winlink.org/GetRmsPacketStationsForMap")
	request.send(
		'<?xml version="1.0" encoding="utf-8"?>' +
		'<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">' +
		'	<soap:Body>' +
		'   <GetRmsPacketStationsForMap xmlns="http://www.winlink.org/">' +
        '       <strSecurityCode>14435FE8-C24A-4EAD-9A52-82AC644B0D43</strSecurityCode>' +
		'		<intActivityHours>' + activityHours + '</intActivityHours>' + 
		'		<strGroupFilter>0,1,2,4</strGroupFilter>' + 
		'	</GetRmsPacketStationsForMap>' +
		'	</soap:Body>' +
		'</soap:Envelope>'
	);
}

//create content for legend area
function initLegend() {
    var legend = document.getElementById("legend"); 
    var D = new Date();
    legend.innerHTML = D.toUTCString() + '&nbsp;&nbsp;&nbsp;' + 
    '<img src="images/green_dot.png" alt=""> Current, ' + 
    '<img src="images/yellow_dot.png" alt=""> Status received within ' + hoursYellow + ' hours, ' + 
    '<img src="images/red_dot.png" alt=""> Status older than ' + hoursYellow + ' hours';
}

function initPage() {
	var args = getQueryString();
	argCallsign = args['callsign'];
	if (argCallsign) {
		argCallsign = argCallsign.toUpperCase();
		argArray = argCallsign.split(',');
		if (argArray.length > 1)
		  argCallsign = '';
	} else {
		argCallsign = '';
	}
	
	if (GBrowserIsCompatible()) { 
		createMap();
		createIcons();
		initLegend();
		loadStations();
	} else {
		document.write("This web page is not currently compatible with your browser.");
	}
}
			
