﻿/// <reference path="scripts/VeJavaScriptIntellisenseHelper.js" />
/// <reference path="scripts/jquery.intellisense.js"/>

// NOTE:    The above reference is used only at design time.
//          It provides a skeleton of the VE API to enable 
//          intellisense.  Notice that the Default.aspx 
//          page DOES NOT reference VeJavaScriptIntellisenseHelper.js.
//          At run time, we use the real VE API.

// KNOWN ISSUE: Due to the nature of JavaScript, there is no way
//              to know the type of a page level variable inside
//              a given function in the page when the variable
//              was instatiated in another function.  The side
//              effect of this is that you will not get 
//              intellisense for a page leverl map variable 
//              outside of the function in which it was instantiated.

// WORKAROUND:
//  USE AT DESIGN TIME TO GET INTELLISENSE FOR A PAGE LEVEL map VARIABLE
//var map;

//if (typeof (DESIGN_TIME) == 'undefined')
//{
  //  map = null;
//}
//else
//{
  //  var map = new VEMap();
//}

// WORKAROUND:
//  YOU WILL PROBABLY WANT TO COMMENT THE WORKAROUND ABOVE AND UNCOMMENT THE LINE
//  BELOW FOR PRODUCTION.
//var map; 

//NOTE:
//  You really don't have to comment/uncomment while you are developing.  
//  You just want to make sure you fix things for production:).

var _units = null;
var _unitEventHistory = null;
var _markerInfoWindowHtml = null;
var _routeOverlays = null;
var _routeLayer = null;
var _routeLayerSourceSpec = null;
var _defaultMapCentre = null;
var _defaultTLLat = 0;
var _defaultTLLon = 0;
var _defaultBRLat = 0;
var _defaultBRLon = 0;
var _defaultMapView;
var _serverLocalDiff;
var _unitMapZoomLayer = null;
var map = null;
var selectedServiceRouteOverlay = null;
var selectedServiceRouteOverlayPath = null;

var _restrictOperatingTimes = null;
var _operatingStartTime = null;
var _operatingEndTime = null;


function resize() {
    var w = document.documentElement.clientWidth-10;
    var h = document.documentElement.clientHeight-111-5;

    //var w = document.getElementById('myMap').style.width;
    //var h = document.getElementById('myMap').style.height;

    if (map != null) {
	setMapSize(w,h)
	map.checkResize();
	}
	//map.Resize(w, h);
};
window.onresize = resize;

function setMapSize(w,h) {
	    //if (Ext.log!==undefined) Ext.log('_setMapSize begin');
	    if(h>0 && w>0) {
		    var c=this.map.getContainer();
		    c.style.height=h+'px';
		    c.style.width=w+'px';
        }
}

function pageLoad()
{

	map = new GMap2(document.getElementById("myMap"));
	
	GEvent.addListener(map, 'zoomend', mapZoomHandler);
	//GEvent.addListener(map, 'addoverlay', mapAddOverlayHandler)
	
	
    //map.SetDashboardSize(VEDashboardSize.Small);
	
	_restrictOperatingTimes = document.getElementById('hidRestrictOperatingTime').value;
	
	if(_restrictOperatingTimes == "True") {
	
		var operatingStartDT = new Date();
		operatingStartDT.setHours(document.getElementById('hidOperatingStartHour').value);
		operatingStartDT.setMinutes(document.getElementById('hidOperatingStartMinute').value);
		operatingStartDT.setSeconds(0);
		
		var operatingEndDT = new Date();
		operatingEndDT.setHours(document.getElementById('hidOperatingEndHour').value);
		operatingEndDT.setMinutes(document.getElementById('hidOperatingEndMinute').value);
		operatingEndDT.setSeconds(0);
		
		_operatingStartTime = operatingStartDT;
		_operatingEndTime = operatingEndDT;
		
	}
	
    _defaultTLLat = parseFloat(document.getElementById('hidDefaultMapTLLat').value);
    _defaultTLLon = parseFloat(document.getElementById('hidDefaultMapTLLon').value);
    _defaultBRLat = parseFloat(document.getElementById('hidDefaultMapBRLat').value);
    _defaultBRLon = parseFloat(document.getElementById('hidDefaultMapBRLon').value);
    if (_defaultTLLat != 0 || _defaultTLLon != 0 || _defaultBRLat != 0 || _defaultBRLon != 0) {
        _defaultMapView = new VELatLongRectangle(new VELatLong(_defaultBRLat, _defaultBRLon), new VELatLong(_defaultTLLat, _defaultTLLon));
        _defaultMapCentre = new VELatLong((_defaultTLLat + _defaultBRLat) / 2, (_defaultTLLon + _defaultBRLon) / 2);
    }
	var centreLat=(61.35461+50.87531)/2;
	var centreLon=(-12.08496+1.669922)/2;
	_defaultMapCentre=new GLatLng(centreLat, centreLon);

	
	map.setCenter(_defaultMapCentre, 5);
	
	//Positioning of map controls below
	var topLeft= new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(80,10));
    var topLeftb= new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(10,10));
	//map.addMapType(G_SATELLITE_3D_MAP); 

	map.addControl(new ExtMapTypeControl({showTraffic: true, showTrafficKey: true}), topLeft);
	map.addControl(new GLargeMapControl3D (), topLeftb);
	map.addControl(new GScaleControl());
	map.enableScrollWheelZoom();
	map.enableContinuousZoom();
	window.onresize();
	
    map.load = new function() {
        
        _units = new Array();
        _unitEventHistory = new Array();
		_markerInfoWindowHtml = new Array();
		_routeOverlays = new Array();
        routeMapURL = document.getElementById('hidRouteMapURL').value;


        DrawUnits();
        window.setInterval(onSessionDataCheckTimer, 20000);
        //window.setTimeout(resetMapView, 250);
        window.setInterval(displayTime, 1000);
		
    }
	
	
    //GetLastReportedEvents(Function.createDelegate(this, this._wsGetSessionData), Function.createDelegate(this, this._wsError));
}

function mapZoomHandler(oldZoomLevel,newZoomLevel) {
	//alert(oldZoomLevel + ',' + newZoomLevel);
	
	//When the map reaches a certain zoom level need to control the visibility of any route overlays
	//console.log(oldZoomLevel + ',' + newZoomLevel);
		if(selectedServiceRouteOverlay!=null&&selectedServiceRouteOverlayPath!='') {
			if(newZoomLevel>13) 
				selectedServiceRouteOverlay.show();
			else
				selectedServiceRouteOverlay.hide();
	}
	
}

// function mapAddOverlayHandler(overlay) {
 // //alert('test');
 // if(selectedServiceRouteOverlay!=null&&selectedServiceRouteOverlayPath!='') {
			// if(map.getZoom()>13) 
				// selectedServiceRouteOverlay.show();
			// else
				// selectedServiceRouteOverlay.hide();
	// }
// }

function padlength(what) {
    var output = (what.toString().length == 1) ? "0" + what : what
    return output
}

function displayTime() {
    //var montharray = new Array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
    if (_serverLocalDiff == null) {
        var serverDate = new Date(parseFloat(document.getElementById("hidServerTime").value));
        _serverLocalDiff = serverDate.getTime() - _localDate.getTime() +_localDate.getTimezoneOffset()*60000;
    }
    var serverDate = new Date(new Date().getTime() + _serverLocalDiff);
	 
	 
	// var _operatingStartTime = null;
	//var _operatingEndTime
	if(_restrictOperatingTimes == "True") {
		
		if(serverDate>_operatingEndTime) {
			document.getElementById("btnLogout").click();
		}
		else {
			document.getElementById("servertime").innerHTML = padlength(serverDate.getHours()) + ":" + padlength(serverDate.getMinutes()) + ":" + padlength(serverDate.getSeconds());
		}
	}
	else {
	
		 document.getElementById("servertime").innerHTML = padlength(serverDate.getHours()) + ":" + padlength(serverDate.getMinutes()) + ":" + padlength(serverDate.getSeconds());
	}
	
    //_serverDate.setSeconds(_serverDate.getSeconds() + 1);
    //var datestring = montharray[_serverDate.getMonth()] + " " + padlength(_serverDate.getDate()) + ", " + _serverDate.getFullYear();
   
}

function onRouteMapLoad(feed) {
    //Turn off ugly pushpins!
    var ctr = 0;
    var length = this.Layer.GetShapeCount();
    for (ctr; ctr < length; ctr++) {
		feed.Annotations[ctr].SetZIndex(100);
        //If not polyline, e.g. a route overlay ensure no icon is displayed on the map
        if (feed.Annotations[ctr].Type == "Polyline") {
            feed.Annotations[ctr].HideIcon('');

        }
        else {
			feed.Annotations[ctr].SetMinZoomLevel(10);
            feed.Annotations[ctr].SetCustomIcon('<img src="images/busstop.gif">');
        }

    }
}

function onSessionDataCheckTimer() {
    PageMethods.GetUpdatedLastReportedEvents(_wsGetUpdatedSessionData, _wsError);
}

function DrawUnits() {
    //if(_lre.length-1>0)
	//if(_lre.length-1>0)
    //{	
		// if(_lre.length-2==0) {
		// $get("lblDropDownList").style.visibility="hidden";
		// $get("ddlUnit").style.visibility="hidden";
		// $get("btnZoom").style.visibility="hidden";
		// $get("lblchkFollow").style.visibility="hidden";
		// $get("chkFollow").style.visibility="hidden";
		// }
		
		//Ignore First and Last Array objects as they represent the trackinglist and service allocations respectively
		//So only prcess array objects inbetween which are the last reported event and nested history array
        for (i = 1; i < _lre.length-1; i++) {
        _addUnit(_lre[i],_lre[_lre.length-1]);
            
        }
		
		
        
		
		//If there are no units present in the Tracking List array then add a message to bottom footer
		 if(_lre[0].length==0) {
			if(document.getElementById('hidAppTheme').value=="LoneGuardianDefault")
				document.getElementById('lblServiceStatus').innerHTML='';
			 else
				document.getElementById('lblServiceStatus').innerHTML='No vehicles are currently operating on any services.';
		}
		
		if(_lre[_lre.length-1].length>0) {
				
				var length = document.getElementById('ddlUnit').options.length;
				

				
				var allOption = new Option('-Show All-', 'All');
					document.getElementById('ddlUnit').options.add(allOption);
				for(var i = 0; i < _lre[_lre.length-1].length; i++)
				{
					var newOption = new Option(_lre[_lre.length-1][i][1],_lre[_lre.length-1][i][2]==null?"":_lre[_lre.length-1][i][2]);

					//Need to also add on the Service ID and RouteMapURL attributes too
					newOption.setAttribute("RouteID",_lre[_lre.length-1][i][0]);
					newOption.setAttribute("RouteMapURL",_lre[_lre.length-1][i][3]);
					document.getElementById('ddlUnit').options.add(newOption);
					
					//_routeOverlays[_lre[_lre.length-1][i][0]] = _lre[_lre.length-1][i][3];
				}
				
				//Need to also change the labels used for drop down, e.g. 'Service' instead if 'Vehicle'
				document.getElementById('lblDropDownList').innerText="Show Service: ";
				//$get("btnZoom").style.visibility="hidden";
				//$get("lblchkFollow").style.visibility="hidden";
				document.getElementById('lblchkFollow').innerText="Follow Service";
				//$get("chkFollow").style.visibility="hidden";
				
			}
			else
			{
				//If it is null then we assume ddlUnit is a list of unit names so we need to update these according to tracking list changes
				//Can just use the history objects coming back in main array collection as these will reflect the new tracking list changes
				var allOption = new Option('-Show All-', 'All');
					document.getElementById('ddlUnit').options.add(allOption);
				//Only remove options from index 1 as we want to keep the Show All option anyway so no point in removing it to
				//only re-add it later!
				var i;
				for(i=document.getElementById('ddlUnit').options.length-1;i>=1;i--)
				{
					document.getElementById('ddlUnit').remove(i);
				}
				//var allOption = new Option('-Show All-', 'All');
					//document.getElementById('ddlUnit').options.add(allOption);
				for(var i = 1; i < _lre.length-1; i++)
				{
					var newOption = new Option(_lre[i][3],_lre[i][0]);
					//Need to also add on the routenameurl attr too
					document.getElementById('ddlUnit').options.add(newOption);
				}
			}
			
			resetMapView();
			
			//Having perfomed the neccessary unit and history layer additions and populated the drop down list correctly
			//Now need to set the map view.
			
			//if (_defaultMapView == null) {
				//map.SetMapView(_historylayer.GetBoundingRectangle());
			
			//}
}

function _is24x24Icon(iconNum) {
    return ((iconNum >= 10090 && iconNum <= 10125) || (iconNum >= 20007 && iconNum <= 20028) || (iconNum >= 50000 && iconNum <= 50035));
}

function _wsGetUpdatedSessionData(data) {

    //Check incoming data array param, compare the untID's to _unitlayer untID's, if a null data[0] array part
    //then we have no tracking list changes so we just process any new position data in the else block
    if (data[0]!=null) {

        if (data[0].length==0)
        {
           
            //Empty tracking list returned, so remove all unit and history shapes off map
			//Populate list of untIDs in array below
			untIDArray = new Array();
			//for (var x = 0; x < _markers.length; x++) {
			for(var untID in _units)
			{
				if(_units[untID].category=="unit")
					untIDArray.push(_units[untID].untID)
				//untIDArray.push(_unitlayer.Annotations[x].untID)
			}
			//Loop through untIDArray and call the _deleteUnit method
			for (var i = 0; i < untIDArray.length; i++) {
				_deleteUnit(untIDArray[i]);
			}
            
			//Only remove options from index 1 as we want to keep the Show All option anyway so no point in removing it to
			//only re-add it later!
			var i;
			for(i=document.getElementById('ddlUnit').options.length-1;i>=1;i--)
			{
				document.getElementById('ddlUnit').remove(i);
			}
			
					
			//document.getElementById('lblServiceStatus').innerHTML='No vehicles are currently operating on any services.';
			//if(_lre[0].length==0) {
			if(document.getElementById('hidAppTheme').value=="LoneGuardianDefault")
				document.getElementById('lblServiceStatus').innerHTML='';
			 else
				document.getElementById('lblServiceStatus').innerHTML='No vehicles are currently operating on any services.';
		
			//Reset map to default world view
			//map.SetMapView(_historylayer.GetBoundingRectangle());
        }
        else
        {
			
		//If units are present in the data[0] array check them against the _units array and for any not
		//present in the array call the deleteUnits() method to remove them and their history events from
		//the map view

			for(var untID in _units)
			{
				if (untID!='remove'&&untID!='indexOf') {
					//console.log('lookup '+untID);
					untID = _units[untID].untID;
					var found = false;
					for (var x = 0; x < data[0].length; x++) {
						if(data[0][x]==untID){
							found=true;
							//break;
							}
					   
					}
					if(found==false){
						_deleteUnit(untID);
					}
				}
			}


            var s;

            for (var i = 1; i < data.length-1; i++) {

                var untID=data[i][0];
                s = _units['u'+untID];
                //If s is not null then the unit is already present on the map so only process the new history data
                //for it and update accordingly
                if (s != null) {
					_updateUnit(data[i], data[data.length-1]);
                }
                //If s is null then the unit is not present on the map so we need
                //to add it and the history data for it too
                else {
					_addUnit(data[i], data[data.length-1]);
                }
			
            }

			//Must also update the ddlUnit control with any new units or service Allocation entries
			//Need to trap the users current service selection, store the Service ID in a param and use to re-select the service
			//later on
			var routeID = "";
			if(document.getElementById('ddlUnit').options[document.getElementById('ddlUnit').selectedIndex].attributes.getNamedItem("RouteID")!=null) {
				routeID = document.getElementById('ddlUnit').options[document.getElementById('ddlUnit').selectedIndex].attributes.getNamedItem("RouteID").value;
			}
			
			//Check if final array object in data array list is not null, if not then we need to refresh the ddlUnit options collection
			if(data[data.length-1].length>0) {
				
				var length = document.getElementById('ddlUnit').options.length;
				
				//Only remove options from index 1 as we want to keep the Show All option anyway so no point in removing it to
				//only re-add it later!
				var i;
				for(i=document.getElementById('ddlUnit').options.length-1;i>=1;i--)
				{
					document.getElementById('ddlUnit').remove(i);
				}

				for(var i = 0; i < data[data.length-1].length; i++)
				{
					var newOption = new Option(data[data.length-1][i][1],data[data.length-1][i][2]==null?"":data[data.length-1][i][2]);
					//Need to also add on the routenameurl attr too
					//document.getElementById('ddlUnit').options.add(newOption);
					newOption.setAttribute("RouteID",_lre[_lre.length-1][i][0]);
					newOption.setAttribute("RouteMapURL",_lre[_lre.length-1][i][3]);
					document.getElementById('ddlUnit').options.add(newOption);
					
					//_routeOverlays[data[data.length-1][i][0]] = data[data.length-1][i][3];
				}
				
				//Loop back through service list again and re-select the option that has a matching service ID trapped in the routeID param earlier
				for(var i = 0; i < document.getElementById('ddlUnit').options.length; i++) {
					if(document.getElementById('ddlUnit').options[i].attributes.getNamedItem("RouteID")) {
						if(document.getElementById('ddlUnit').options[i].attributes.getNamedItem("RouteID").value==routeID)
							document.getElementById('ddlUnit').options.selectedIndex=i;
					}
				}
				
			}
			else
			{
			//If it is null then we assume ddlUnit is a list of unit names so we need to update these according to tracking list changes
			//Can just use the history objects coming back in main array collection as these will reflect the new tracking list changes
				//alert('SA array is empty, so we just process the normal units list');
				
				//Only remove options from index 1 as we want to keep the Show All option anyway so no point in removing it to
				//only re-add it later!
				var i;
				for(i=document.getElementById('ddlUnit').options.length-1;i>=1;i--)
				{
					document.getElementById('ddlUnit').remove(i);
				}
				//var allOption = new Option('-Show All-', 'All');
					//document.getElementById('ddlUnit').options.add(allOption);
				for(var i = 1; i < data.length-1; i++)
				{
					var newOption = new Option(data[i][3],data[i][0]);
					//Need to also add on the routenameurl attr too
					document.getElementById('ddlUnit').options.add(newOption);
				}
			}
			
			//Reset the map display based on the selected ddlUnt value
			//filterMapDisplay(document.getElementById('ddlUnit').value);
			document.getElementById('lblServiceStatus').innerHTML='';
        }
        
    }
	else{
		
		//null data[0] array part returned so we have no tracking list changes so we just process any new position data below
		document.getElementById('lblServiceStatus').innerHTML='';
		//Need to trap the users service selection, store the Service ID in a param
		var routeID = "";
		if(document.getElementById('ddlUnit').options[document.getElementById('ddlUnit').selectedIndex].attributes.getNamedItem("RouteID")!=null) {
			routeID = document.getElementById('ddlUnit').options[document.getElementById('ddlUnit').selectedIndex].attributes.getNamedItem("RouteID").value;
		}
	
		//Check if final array object in data array list is not null, if not then we need to refresh the ddlUnit options collection
		//So just updating the service names and untID values
		if(data[data.length-1].length>0) {
					
			var length = document.getElementById('ddlUnit').options.length;
			
			//Only remove options from index 1 as we want to keep the Show All option anyway so no point in removing it to
			//only re-add it later!
			var i;
			for(i=document.getElementById('ddlUnit').options.length-1;i>=1;i--)
			{
				document.getElementById('ddlUnit').remove(i);
			}

			for(var i = 0; i < data[data.length-1].length; i++)
			{
				var newOption = new Option(data[data.length-1][i][1],data[data.length-1][i][2]==null?"":data[data.length-1][i][2]);
				//Need to also add on the routenameurl attr too
				//document.getElementById('ddlUnit').options.add(newOption);
				newOption.setAttribute("RouteID",data[data.length-1][i][0]);
				newOption.setAttribute("RouteMapURL",data[data.length-1][i][3]);
				document.getElementById('ddlUnit').options.add(newOption);
				//_routeOverlays[data[data.length-1][i][0]] = data[data.length-1][i][3];
			}
			
			//Loop back through service list again and re-select the option that has a matching service ID trapped in the routeID param earlier
			for(var i = 0; i < document.getElementById('ddlUnit').options.length; i++) {
				if(document.getElementById('ddlUnit').options[i].attributes.getNamedItem("RouteID")) {
					if(document.getElementById('ddlUnit').options[i].attributes.getNamedItem("RouteID").value==routeID)
						document.getElementById('ddlUnit').options.selectedIndex=i;
				}
			}

			
			
			//After all updates are processed reset the map view based on whatever selection is made on ddlUnit control
			//filterMapDisplay(document.getElementById('ddlUnit').value);
		}
		
		//Process any new position data for the existing units if present in the relevant data array collection
			if(data.length-1 > 1) {
				for (var i = 1; i < data.length-1; i++) {
					var untID=data[i][0];
					_updateUnit(data[i],data[data.length-1]);

				}	
			}
			else {
				//If there are no new history arrays to process then we need to check each existing unit against
				//the remaining array object contain service and unit allocations and if any units have had a change in service allocation
				//need to call the _updateUnitServiceDetail to amend the title text for these units which appears in the hover pop up window
				//on map
				for(var untID in _units)
				{
					if (untID!='remove'&&untID!='indexOf') {
						_updateUnitServiceDetail(untID, data[data.length-1]);
					}
				}
			}
		
		filterMapDisplay(document.getElementById('ddlUnit').value);
	}
}

function _updateUnitServiceDetail(untID, contractData) {
	
	//This is a bit of hack to re label any new service allocations, but it DOES NOT take into account any new
	//unit name changes
	
	// var s = _units[untID];
	// var unitName = _units[untID].getTitle().split(' - ')[1];
	
	// if(contractData.length>0) {
		// var ctr=0;
		// var string = "";
		// for(var i = 0; i < contractData.length; i++)
		// {
			
			// if(contractData[i][2]!=null&&contractData[i][2].indexOf(s.untID)!=-1) {
					// string += contractData[i][1] + "/";
					// ctr++;
				// }
		// }
		// //If no match is found for the untID in any of the contract array items then default to unt name along with 'unallocated' status text 
		// if(ctr==0)
			// s.SetTitle('Unallocated - ' + unitName);
		// else {
			// var strLen = string.length; 
			// string = string.slice(0,strLen-1); 

			// s.SetTitle(string + ' - ' + unitName);
		// }
	// }
	// else{
			
		// s.SetTitle(unitName);
	// }
}

function _addUnit(unitData, contractData) {

	// //If units are derived from a service list (jobs) then the Title of the shape layer needs to show both the vehicle and service name
	
	var title = "";
	
	if(contractData.length>0) {
		//ctr var to track when a match is found
		var ctr=0;
		var string = "";
		for(var i = 0; i < contractData.length; i++)
		{
			if(contractData[i][2]!=null&&contractData[i][2].indexOf(unitData[0])!=-1) {
				string += contractData[i][1] + "/";
				ctr++;
			}
		}
		//If no match is found for the untID in any of the contract array items then default to unt name along with 'unallocated' status text 
		if(ctr==0)
			title='Unallocated - ' + unitData[3];
		else {
			var strLen = string.length; 
			string = string.slice(0,strLen-1); 
			title=string + ' - ' + unitData[3];
		}
	}
	else{
		title=unitData[3];
	}
	
	
	//Need to add all unit markers to the _markers Array but setting categories for units and history types so 
	//we can use these in later code
	 var unitIcon = new GIcon(G_DEFAULT_ICON);
	 var iconNum = unitData[5];
	 unitIcon.image = "http://beta.pinpointers.com/images/mapicons/" + iconNum + ".gif";
	 unitIcon.shadow="";
	 if(_is24x24Icon(iconNum)) {
			unitIcon.iconSize = new GSize(24,24);
			unitIcon.iconAnchor = new GPoint(12,12);
	}
	else {
			unitIcon.iconSize = new GSize(16,16);
			unitIcon.iconAnchor = new GPoint(8,8);
	}
	
	
		
	var markerOptions = { icon:unitIcon, zIndexProcess:importanceOrder };
	
	
	var unitPoint = new GLatLng(unitData[1], unitData[2]);
	var unitHtml = '<b>'+title+'</b><br/><br/>'+unitData[4];
	var unitMarker = createMarker(unitPoint,unitHtml,markerOptions,unitData[0],null,"unit",2)
	
	_units['u'+unitMarker.untID] = unitMarker;
	
	
	//The _markerInfoWindowHtml array is used for storing HTML strings keyed on untID if a unit icon and hitID if a history one.
	//this array is populated and managed throughout this code so that whenever position updates come through the correct text is stored for that position 
	//This is then used in the mouseover code found in the createMarker() function further down this code.
	_markerInfoWindowHtml[unitMarker.untID] = unitHtml;
	
	map.addOverlay(unitMarker);

	// Draw the recent history arrows
	_unitEventHistory[unitMarker.untID] = new Array();
		var historyArray=unitData[7];
		if (historyArray.length > 0) {
		 for (j = 0; j < historyArray.length; j++) {
			
			 var historyIcon = new GIcon(G_DEFAULT_ICON);
			 var iconNum = 50000 + (Math.round(historyArray[j][4] / 10) % 36);
			 historyIcon.image = "http://beta.pinpointers.com/images/mapicons/" + iconNum + ".gif";
			 historyIcon.shadow="";
			 historyIcon.iconSize = new GSize(16,16);
			 historyIcon.iconAnchor = new GPoint(8,8);

			var historyMarkerOptions = { icon:historyIcon, zIndexProcess:importanceOrder };
			
			var historyPoint = new GLatLng(historyArray[j][1], historyArray[j][2]);
			var historyHtml = '<b>'+title+'</b><br/><br/>'+historyArray[j][3];
			var historyMarker = createMarker(historyPoint,historyHtml,historyMarkerOptions,unitData[0],historyArray[j][0],"history",1)
			var hitID = historyArray[j][0];
			_unitEventHistory[unitMarker.untID][hitID] = historyMarker;
			_markerInfoWindowHtml[hitID] = historyHtml;
			map.addOverlay(historyMarker);
			
		 }
	 }
	 
	 //resetMapView();

}

function _updateUnit(unitData, contractData) {
    
    var untID = unitData[0];
    var s = _units['u'+untID];

	var title = "";	
	if(contractData.length>0) {
		//ctr var to track when a match is found
		var ctr=0;
		var string = "";
		for(var i = 0; i < contractData.length; i++)
		{
			if(contractData[i][2]!=null&&contractData[i][2].indexOf(unitData[0])!=-1) {
				string += contractData[i][1] + "/";
				ctr++;
			}
		}
		//If no match is found for the untID in any of the contract array items then default to unt name along with 'unallocated' status text 
		if(ctr==0)
			title='Unallocated - ' + unitData[3];
		else {
			var strLen = string.length; 
			string = string.slice(0,strLen-1); 
			title=string + ' - ' + unitData[3];
		}
	}
	else{
		title=unitData[3];
	}
	
	var newTitle = "<b>"+title+"</b><br/><br/>"+unitData[4];
	_markerInfoWindowHtml[untID] = newTitle;
	
	var pos = new GLatLng(unitData[1], unitData[2]);
	s.setLatLng(pos);
	var validHitIDs=new Array();
	historyArray = unitData[7];
	if (historyArray.length > 0) {
		for (j = 0; j < historyArray.length; j++) {
			var hitID = historyArray[j][0];
			validHitIDs[hitID]=99;
			
			 var historyIcon = new GIcon(G_DEFAULT_ICON);
			 var iconNum = 50000 + Math.round(historyArray[j][4] / 10);
			 historyIcon.image = "http://beta.pinpointers.com/images/mapicons/" + iconNum + ".gif";
			 historyIcon.shadow="";
			 historyIcon.iconSize = new GSize(16,16);
			 historyIcon.iconAnchor = new GPoint(8,8);


			var historyMarkerOptions = { icon:historyIcon, zIndexProcess:importanceOrder };
			
			var hs = _unitEventHistory[untID][hitID];
			if (hs == null) {
				//createMarker(point,html,markerOptions,untID,hitID,category,importance)
				var histPoint = new GLatLng(historyArray[j][1], historyArray[j][2]);
				var histHtml = '<b>'+title+'</b><br/><br/>'+historyArray[j][3];				
				hs = createMarker(histPoint,histHtml,historyMarkerOptions,s.untID,hitID,"history",1)
				_unitEventHistory[s.untID][hitID] = hs;
				_markerInfoWindowHtml[hitID] = histHtml;
				//If the updates belong to a untID that is not part of a selected service from dll control we must hide the shape
				//Otherwise it gets shown on the map as an event that is not part of the selected untIDs belonging to the ddl option
				if(document.getElementById('ddlUnit').value=='all'||document.getElementById('ddlUnit').value.indexOf(s.untID)==-1) {
					hs.hide();
				}
				map.addOverlay(hs);
				
			} else {
				//hs.SetPoints([new VELatLong(historyArray[j][1], historyArray[j][2])]);
				hs.setLatLng(new GLatLng(historyArray[j][1], historyArray[j][2]));
				var newHistTitle = "<b>"+title+"</b><br/><br/>"+historyArray[j][3];
				_markerInfoWindowHtml[hitID] = newHistTitle;
				//document.getElementById('div'+untID).innerHtml=newHistTitle;
				//hs.untID = s.untID;
			}
			hs.untID = s.untID;
			//hs.SetTitle(s.GetTitle());
			//hs.SetDescription(historyArray[j][3]);
			//iconNum = 50000 + Math.round(historyArray[j][4] / 10);
			//if (_is24x24Icon(iconNum)) {
				//icon = '<img src="http://beta.pinpointers.com/images/mapicons/24/' + iconNum + '.gif" style="margin:1px">';
			//} else {
				//icon = '<img src="http://beta.pinpointers.com/images/mapicons/24/' + iconNum + '.gif" style="margin:5px">';
			//}
			//hs.SetCustomIcon(icon);
		}
	}

	// Now delete any _unitEventHistory shapes which aren't in validHitIDs
	for (var hitID in _unitEventHistory[untID]) {
		if(hitID!='remove'&&hitID!='indexOf')
			{
				if (validHitIDs[hitID] != 99) {
					s = _unitEventHistory[untID][hitID];
					map.removeOverlay(s);
					delete _unitEventHistory[untID][hitID];
					delete _markerInfoWindowHtml[hitID];
				}
			}
	}
}



function createMarker(point,html,markerOptions,untID,hitID,category,importance) {
        var marker = new GMarker(point,markerOptions);
        marker.untID=untID;
		marker.hitID=hitID;
		marker.category=category;
		marker.importance=importance;
		
		var infoWindowOpts = {
			maxWidth:250
		};
		
        // The new marker "mouseover" listener        
		GEvent.addListener(marker,"mouseover", function() {
			
			var newHtml;
			if(marker.untID!=null&&marker.hitID==null)
				newHtml = _markerInfoWindowHtml[untID]
			else if(marker.untID!=null&&marker.hitID!=null)
				newHtml = _markerInfoWindowHtml[hitID]
			
			marker.openInfoWindowHtml(newHtml, infoWindowOpts)
		  
		  
		  });
		  //GEvent.addListener(marker,"mouseover", updateInfoWindowHtml(marker));        

        return marker;
}

// function updateInfoWindowHtml(marker, infoWindowOpts) {
	
	// marker.openInfoWindowHtml('testing', infoWindowOpts);
	
// } 

function _deleteUnit(untID) {

	
	//Remove unit from unitlayer, units array, history layer and drop down control

	//_unitlayer.DeleteShape(_units['u'+untID]);
	map.removeOverlay(_units['u'+untID]);
	delete _units['u'+untID];
	delete _markerInfoWindowHtml[untID];
    // Now delete any _unitEventHistory shapes which aren't in validHitIDs
	for (var hitID in _unitEventHistory[untID]) {
		if(hitID!='remove'&&hitID!='indexOf'){
			s = _unitEventHistory[untID][hitID];
			//_historylayer.DeleteShape(s);
			map.removeOverlay(s);
			delete _unitEventHistory[untID][hitID];
			delete _markerInfoWindowHtml[hitID];
		}
	}
	delete _unitEventHistory[untID];
}

function _handleError(functionName, result) {
    //alert("ERROR!: " + result);
    //document.getElementById('message').innerText = result;
    var m=result.get_message();
    var SDKerror=m.split(':')[0];
    if (m.split(':')[1]!=undefined) m=m.split(':')[1].trim();
    if ((SDKerror+0)==0) SDKerror=null;
//    this._trace('_wsError: '+m+' ('+SDKerror+')');
//    this._waitingForSessionDataResponse=false;
    if (SDKerror == 2) {
        document.getElementById('btnLogout').click();
        //alert("Your session has ended");
        //this._raiseEvent("sessionend");
    } else {
//      this._raiseEvent("webserviceerror", {functionName: functionName, result: result, message: m, SDKErrorCode: SDKerror});
    }
}
    
function _wsError(result) {
    _handleError("", result);
    
}




function importanceOrder (marker,b) {
        return GOverlay.getZIndex(marker.getPoint().lat()) + marker.importance*1000000;
      }

function resetMapView() {
	
	//Retrieve the lat\lons of any markers that are visible and populate a GLatLngBounds object for centering the map on
	var bounds = new GLatLngBounds();
	
	for(var untID in _units) {
		if (untID!='remove'&&untID!='indexOf') {
			if(_units[untID].isHidden()==false)
				bounds.extend(_units[untID].getLatLng());
		}
	}
	
	for(var untID in _unitEventHistory) {
		if (untID!='remove'&&untID!='indexOf') {
			for(hitID in _unitEventHistory[untID]) {
				if (hitID!='remove'&&hitID!='indexOf') {
					if(_unitEventHistory[untID][hitID].isHidden()==false)
					bounds.extend(_unitEventHistory[untID][hitID].getLatLng());
				}
			}
		}
	}
	
	
	//Clear any route overlays displayed on the map
	// for(var i=0; i<_routeOverlays.length; i++) {
		// if (i!='remove'&&i!='indexOf') {
			// map.removeOverlay(_routeOverlays[i]);
			// delete _routeOverlays[i];
		// }
	// }
	
	//if(selectedServiceRouteOverlay!=null) {
		//map.removeOverlay(selectedServiceRouteOverlay);
		//selectedServiceRouteOverlay = null;
	//}
	
	//Check for existence of routeMapURL attributes, if present need to draw the kml
	
	//Two lines of code get called everytime so causes a redraw of kml if the selected service is still the same as previous call, needs review!
	
	
	//http://access.pinpointers.com/KMLTest/Souls_Contract_48_RouteOverlay.kml
	
	//var routeMapURL = "";
	var routeID = null;
	
	if(document.getElementById('ddlUnit').options[document.getElementById('ddlUnit').selectedIndex].attributes.getNamedItem("RouteMapURL")!=null) {
			routeMapURL = document.getElementById('ddlUnit').options[document.getElementById('ddlUnit').selectedIndex].attributes.getNamedItem("RouteMapURL").value;
			//routeID = document.getElementById('ddlUnit').options[document.getElementById('ddlUnit').selectedIndex].attributes.getNamedItem("RouteID").value;
			
			
	}
	
	
	//If a route is already present on map, we need to compare to the routeURL attr on the ddl control
	if(selectedServiceRouteOverlay!=null) {
	
		//If no route overlay attribute or its different to the source of the layer on the map already then remove the overlay
		if(routeMapURL==""||routeMapURL!=selectedServiceRouteOverlayPath) {
				map.removeOverlay(selectedServiceRouteOverlay);
				selectedServiceRouteOverlayPath='';
		}
	
	
		if(routeMapURL!=""&&routeMapURL!=selectedServiceRouteOverlayPath) {
				selectedServiceRouteOverlayPath = routeMapURL;
				selectedServiceRouteOverlay = new GGeoXml(routeMapURL);
				selectedServiceRouteOverlay.hide();
				GEvent.addListener(selectedServiceRouteOverlay, 'load', kmlLoadHandler);
				
				
		
		}
		
	}
	//Initial page load
	else {
		if(routeMapURL!="") {
			 selectedServiceRouteOverlayPath = routeMapURL;
			 selectedServiceRouteOverlay = new GGeoXml(routeMapURL);
			 selectedServiceRouteOverlay.hide();
			 //debugger;
			 GEvent.addListener(selectedServiceRouteOverlay, 'load', kmlLoadHandler);
			 // selectedServiceRouteOverlayPath = routeMapURL;
			// map.addOverlay(selectedServiceRouteOverlay);
			
			// mapZoomHandler(null,map.getZoom());

		}
	}
	

		
	
	
	
	
	if($get("chkFollow").checked) {
		if(bounds.equals(new GLatLngBounds())==false) {
			
			map.setZoom(map.getBoundsZoomLevel(bounds));
			//map.setZoom(15);
			map.setCenter(bounds.getCenter());
		}
		else{
			var centreLat=(61.35461+50.87531)/2;
			var centreLon=(-12.08496+1.669922)/2;
			_defaultMapCentre=new GLatLng(centreLat, centreLon);
			map.setCenter(_defaultMapCentre, 5);
		}
		
		
	
		
	}
	
}

function kmlLoadHandler() {
//debugger;
//selectedServiceRouteOverlayPath = routeMapURL;
mapZoomHandler(null,map.getZoom());
				map.addOverlay(selectedServiceRouteOverlay);
				//if(map.getZoom()<14) {
					//selectedServiceRouteOverlay.hide();
					
				//}
				
				
}

// function btnResetViewClick() {

// //For this section, look at use of GLatLngBounds() object and using the extend() method which is equivalent to a getBoundingBox method in VE...

// //var bounds = new GLatLngBounds();
// //Need to loop through the _markers array to calculate the bounds


    // if (map == null) return;
	// var initialMapZoomLevel = map.GetZoomLevel();
	
    // if (_defaultMapView != null) {
        // map.SetMapView(_defaultMapView);
        // map.ZoomIn();
    // } else {
	
		// var routeMapURL="";
		// //Retrive routeMapURL attribute if present
		// if(document.getElementById('ddlUnit').options[document.getElementById('ddlUnit').selectedIndex].attributes.getNamedItem("RouteMapURL")!=null) {
			// routeMapURL = routeMapURL = document.getElementById('ddlUnit').options[document.getElementById('ddlUnit').selectedIndex].attributes.getNamedItem("RouteMapURL").value;
		// }
					
			// //If a route is already present on map, we need to compare to the routeURL attr on the ddl control
			// if(_routeLayer!=null) {
			
				// //If no route overlay attribute or its different to the source of the layer on the map already then delete shapes from routeLayer
				// if(routeMapURL==""||routeMapURL!=_routeLayer.Spec.LayerSource) {
					// _routeLayer.DeleteAllShapes();
					// _routeLayer.Spec.LayerSource="";
				// }

				
				// //if(routeMapURL!=""&&routeMapURL!=_routeLayer.Spec.LayerSource) {
				// if(routeMapURL!=""&&routeMapURL!=_routeLayer.Spec.LayerSource) {

					// _routeLayerSourceSpec = new VEShapeSourceSpecification(VEDataType.ImportXML, routeMapURL, _routeLayer);
					// map.ImportShapeLayerData(_routeLayerSourceSpec, onRouteMapLoad, false);
					
				// }

			
		// }
		// else {
			// //if routeLayer is null, so really on initial page load
			// if(routeMapURL!="") {
			
				// _routeLayer = new VEShapeLayer();
				// _routeLayerSourceSpec = new VEShapeSourceSpecification(VEDataType.ImportXML, routeMapURL, _routeLayer);

				// map.ImportShapeLayerData(_routeLayerSourceSpec, onRouteMapLoad, false);
				
			// }
		// }
			
		// //Only reset the map view if the 'Follow' option is checked otherwise it may take user away from area of map they want to remain on			
		// if($get("chkFollow").checked) {
				
			// if(_unitMapZoomLayer==null||_unitMapZoomLayer.GetShapeCount()==0)
				// view=_unitlayer.GetBoundingRectangle();
			// else
				// view=_unitMapZoomLayer.GetBoundingRectangle();
// //initialMapZoomLevel
			
			
			
			// //If we are zoomed in right at street level, bring out to town level - requested by Jon
			// //if(_routeLayer!=null&&_routeLayer.GetShapeCount()>0) {
				// //if(initialMapZoomLevel > 15)
					// //map.SetZoomLevel(15);
			// //}
			
			// map.SetMapView(view);
		// }
		
		
	// }
// }

function btnZoomIn_Click() {
    // Type the following commented code to experience
    // JavaScript Intellisense:

    //map.ZoomIn();   NOTE: this line of code will not show intellisense without the workaround explained at the beginning of this file.
    map.ZoomIn();
}

function btnZoomClick() {
    //var ddl=document.getElementById("ddlUnit");
    //var untID = ddl.options[ddl.selectedIndex].value;
    //var s = _units['u'+untID];
    //if (s != null) map.SetCenterAndZoom(s.GetPoints()[0], 18);
	view=_historylayer.GetBoundingRectangle();
}

function chkFollowClick() {}

function onTopLeftLogoClick() {
    window.open(document.getElementById("hidTopLeftLogoHyperLinkUrl").value, "ll");
}
function onTopRightLogoClick() {
    window.open(document.getElementById("hidTopRightLogoHyperLinkUrl").value, "rl");
}

function filterMapDisplay(filter) {

	document.getElementById('lblServiceStatus').innerHTML='';
	var routeMapURL = "";
	if(document.getElementById('ddlUnit').options[document.getElementById('ddlUnit').selectedIndex].attributes.getNamedItem("RouteMapURL")!=null) {
			routeMapURL = routeMapURL = document.getElementById('ddlUnit').options[document.getElementById('ddlUnit').selectedIndex].attributes.getNamedItem("RouteMapURL").value;
		}
	
	if(filter!=null&&filter!='All')
	{
		if(filter!='') {
		
			untIDArray = filter.split(',');
			//UntIDs passed in as filter param, so need to show just those units and zoom accordingly on the map
			for (var untID in _units) {
				if (untID!='remove'&&untID!='indexOf') {
					//Counter used to record number of times a unit in filter array item is found in the unitlayer
					var ctr=0;
						for(var i = 0; i < untIDArray.length; i++) {

							if(_units[untID].untID==untIDArray[i]){
								ctr++;
							}

						}
						//If no matches are found in previous loop then we know we need to hide the unit and history shapes
						if(ctr==0)
						{
							_units[untID].hide();

							for (var hitID in _unitEventHistory[untID.replace('u','')]) {
								if(hitID!='remove'&&hitID!='indexOf') {
									_unitEventHistory[untID.replace('u','')][hitID].hide();

									
								}
							}
								
						}
						else
						{

							_units[untID].show();
							
							for (var hitID in _unitEventHistory[untID.replace('u','')]) {
								if(hitID!='remove'&&hitID!='indexOf') {
									_unitEventHistory[untID.replace('u','')][hitID].show();

								}
							}
					}
					//After hiding\showing the correct units on map, need to get bounding box of those that are visible and zoom
					//Also show the associated route if one is present in ddlUnit attributes
					//Set the _unitMapZoomLayer to a suitable zoom level if a routeoverlay is present
					//btnResetViewClick();
					resetMapView();
					
					//Service Status message processing. Check how many untID's are present 
					//alert('Service is running with ' + untIDArray.length + ' vehicles allocated.');
					if(_lre[_lre.length-1].length>0)
					{
					var vehicleText='vehicle';
					if(untIDArray.length>1)
						vehicleText = 'vehicles'
						
						document.getElementById('lblServiceStatus').innerHTML= 'This service is running with ' + untIDArray.length + ' ' + vehicleText + ' currently allocated.'
					}
				}
			}
		}
		else
		{

			var serviceName = document.getElementById('ddlUnit').options[document.getElementById('ddlUnit').selectedIndex].text;
			document.getElementById('lblServiceStatus').innerHTML=serviceName + ': No vehicles are currently operating on this service.';
			
			//Hide all unit and history shape layers
			
			for (var untID in _units) {
				if (untID!='remove'&&untID!='indexOf') {

						_units[untID].hide();
					}
			}
			
			for(var untID in _unitEventHistory) {
				if (untID!='remove'&&untID!='indexOf') {
					for(hitID in _unitEventHistory[untID.replace('u','')]) {
						if (hitID!='remove'&&hitID!='indexOf') {
							_unitEventHistory[untID.replace('u','')][hitID].hide();
						}
					}
				}
			}
			

			
			resetMapView();
		}
	}
	else if (filter=='All')
	{
		
		for (var untID in _units) {
				if (untID!='remove'&&untID!='indexOf') {
						_units[untID].show();
					}
			}
			
		for(var untID in _unitEventHistory) {
			if (untID!='remove'&&untID!='indexOf') {
				for(var hitID in _unitEventHistory[untID.replace('u','')]) {
					if (hitID!='remove'&&hitID!='indexOf') {
						_unitEventHistory[untID.replace('u','')][hitID].show();
					}
				}
			}
		}
		
		resetMapView();

	}

}

function imageMouseOver(img) {
    img.className='mouseover';
}

function imageMouseOut(img) {
    img.className='mouseout';
}



