﻿//Ship tracking script for Atlantic Source network


//----------Global variables-----------------------

var tipos = Array();
var mmsi;
var markers4 = [];
var markers=[];
var allTypes = { 'All':[] };
var stype;
var directorio = "http://www.atlanticsource.es/ais"; // CAMBIAR SEGuN VERSION!!!!
var mgr = null;
var openInfoMarker=null;
var openTooltipMarker=null;

var marker1 = [];
//var pointData = new Object ();
//var listItem = new Object ();

var counter = 0;

var map;

var toggleState=0; //para el mapa meteo
var groundOverlay; //para el mapa meteo

var toggleState2=0; //para el mapa meteo
var groundOverlay2; //para el mapa meteo

//-------------------------------------------------


//-------------------Constants---------------------
var BOAT_POLYG_ZOOM_LEVEL=17; //Max zoom = 19, recommended 16 ant 14

//-------------------------------------------------



//----------Load/unload settings-------------------
window.onload = init;
window.onunload = GUnload;
//-------------------------------------------------


/*
 * Logo-on-map stuff
 */
var PromoControl = function(url) {
	this.url_ = 'http://www.atlanticsource.es';
};

PromoControl.prototype = new GControl(true);

/**
 * Inits the Promo logo on the GMap
 * @param map {GMap2} The map the logo will be plotted on
 * @return The HTML DIV element with the logo
 * @type HTML Element  
 * @author AtlanticSource   
 */
PromoControl.prototype.initialize = function(map) {
	var container = document.createElement("div");
	container.innerHTML = '<img style="cursor:pointer" src="http://www.atlanticsource.es/ltp/providedby.png" border="0">';
	
	container.style.width='120px';
	container.style.height='50px ';
	url = this.url_;
	GEvent.addDomListener(container, "click", function() {
		document.location = url;
	});

	map.getContainer().appendChild(container);

	return container;
};

/**
 * Sets the position of the logo in the map
 * @return The GControl position for the map
 * @type GControlPosition
 * @author AtlanticSource   
 */
PromoControl.prototype.getDefaultPosition = function() {
	return new GControlPosition(G_ANCHOR_BOTTOM_LEFT, new GSize(70, 10));
};


/**
 * Comparison function for binary search troughout a markers array
 * @param marker {boatMarker} This is the boat marker to be compared
 * @param mmsi {String} This is the mmsi to be found
 * @return 0 if boatMarker's mmsi is equal to the given mmsi, 1 if its greater and -1 if tis smaller
 * @type integer  
 * @author Miguel Carlos Mart?nez D?az   
 */
function compBS(marker,mmsi){
	return (marker.mmsi<mmsi)?-1:((marker.mmsi>mmsi)?1:0);
}

/**
 * Comparison function for sorting a markers array
 * @param marker1 {boatMarker} This is the first boat marker to be compared
 * @param marker2 {boatMarker} This is the second boat marker to be compared
 * @return 0 if boatMarker's mmsi is equal to the second's one, 1 if its greater and -1 if its smaller
 * @type integer
 * @author Miguel Carlos Mart?nez D?az   
 */
function compSort(marker1,marker2){
	return (marker1.mmsi<marker2.mmsi)?-1:((marker1.mmsi>marker2.mmsi)?1:0);
}
function posSort(marker1,marker2){
    return (marker1.position<marker2.position)?-1:((marker1.position>marker2.position)?1:0);
}

/**
 * Binary search implementation with custom comparison function
 * @param item {any} item to be found
 * @param comp {function} Comparison function
 * @return If the key is present, it returns the index in the array. Otherwise, it returns -1
 * @type integer
 * @author Miguel Carlos Mart?nez D?az   
 */
Array.prototype.binarySearch = function(item,comp)
{
	var low = 0;
	var high = this.length -1;
	while (low <= high) {
		var mid = Math.floor((low + high) / 2);
		if (comp(this[mid],item)>0)
			high = mid - 1;
		else if (comp(this[mid],item)<0)
			low = mid + 1;
		else
			return mid;
	}
	return -1;
};

/**
 * Linear search implementation. Assumes pre-ordered array. Searches within a given range of indexes
 * @param item {any} item to be found
 * @param comp {function} Comparison function
 * @param low {integer} lower index 
 * @param high {integer} higher index
 * @return If the key is present, it returns the index+1 in the array. Otherwise, it returns the negative value of the upper closest element to the queried one.
 * @type integer
 * @author Miguel Carlos Mart?nez D?az   
 */
Array.prototype.sortedLinearSearch = function(item,comp,low,high)
{
    var i;
    var retSearch;
    
    if(high<0)
        return 0;
     
    for(i=low;i<=high;i++){
        retSearch=comp(this[i],item);
        switch(retSearch){
            case 0:
                return i+1;
            case 1:
                return -i;
        }
    }
	
	return -(high+1);
};



/**
 * 'zoomend' even handler. Intended to manage polygon-icon transitions in high zoom levels
 * @param oldLevel {integer} level before zoom
 * @param newLevel {integer} level after zoom
 * @author Miguel Carlos Mart?nez D?az   
 */
function newZoom(oldLevel, newLevel){
    if((newLevel>BOAT_POLYG_ZOOM_LEVEL)&&(oldLevel<=BOAT_POLYG_ZOOM_LEVEL)){
        for(var k=0;k<markers.length;k++){
            //if(markers[k].visible==true){
                map.addOverlay(markers[k].polygon);
        //    }
        }
    }else if((newLevel<=BOAT_POLYG_ZOOM_LEVEL)&& (oldLevel>BOAT_POLYG_ZOOM_LEVEL)){
        for(var k=0;k<markers.length;k++){
            //if(markers[k].visible==true){
                map.removeOverlay(markers[k].polygon);
            //}
        }
    }      
}

var paintWP = function(){ 
        GDownloadUrl("writeWP.php" , function(data) {
                var positions = [];
          
                var xml = GXml.parse(data);
            var xmlMarkers = xml.documentElement.getElementsByTagName ("markerxml");
            var originalSize=markers.length;
            var markersSearchIndex=0;
            for (var k = 0; k < xmlMarkers.length; k++)  {
                positions[k] = new GLatLng(xmlMarkers[k].getAttribute("latitude"), xmlMarkers[k].getAttribute("longitude"));
                }
            var WPtrack = new GPolyline(positions, "#ffff00", 5);
            positions = null; 
            xmlMarkers = null;       
            //markerAux.track= new GPolyline([new GLatLng(39,0),new GLatLng (40,2)], "#ff0000", 5); 
            map.addOverlay(WPtrack);       
        });
}

/**
 * Setup function
 * @type integer
 * @author AtlanticSource, Miguel Carlos Mart?nez D?az   
 */
function init() {
	var type;
	var j;

    //Changes the body style and opens/closes the sidebar.
	document.getElementById('button-sidebar-hide').onclick = function() { return changeBodyClass('sidebar-right', 'sidebar-off'); };
	document.getElementById('button-sidebar-show').onclick = function() { return changeBodyClass('sidebar-off', 'sidebar-right'); };
    //Changes the body style and opens/closes the leftbar.
	document.getElementById('button-leftbar-hide').onclick = function() { return changeBodyClass('leftbar-right', 'leftbar-off'); };
	document.getElementById('button-leftbar-show').onclick = function() { return changeBodyClass('leftbar-off', 'leftbar-right'); };
	handleResize();

	if (GBrowserIsCompatible()) {
		map = new GMap2(document.getElementById("map"));
		map.addControl(new GLargeMapControl());
		map.addControl(new GMapTypeControl());
		map.addControl(new PromoControl());
		map.enableScrollWheelZoom();
		map.setCenter(new GLatLng(slat, slon), zlvl, G_SATELLITE_MAP);
		//GEvent.addListener(map,'zoomend',newZoom);


		//waypoints - eliminado de la versión regata
		
		
		
		// primera imagen meteo
		var pointSW = new GLatLng(-6.315299,-115.839844);
		var pointNE = new GLatLng(76.100796,15.996094);

		groundOverlay = new GGroundOverlay("https://www.fnmoc.navy.mil/ww3_cgi/dynamic/ww3.w.natl.sig_wav_ht.000.gif",new GLatLngBounds(pointSW, pointNE));
		
		//segunda imagen meteo 
		
		var pointSW2 = new GLatLng(14.689881,-100.107422);
		var pointNE2 = new GLatLng(75.050354,8.964844);
		
		groundOverlay2 = new GGroundOverlay("http://www.opc.ncep.noaa.gov/A_sfc_full_ocean.gif",new GLatLngBounds(pointSW2, pointNE2));
		

		mgrOptions = {borderPadding: 50,trackMarkers : false};
		mgr = new MarkerManager (map,mgrOptions);
        
            
		refreshMap(); //First refresh
		//window.setInterval('refreshMap()',120000); //Schedule refresh

		//drawMarkers();
        
        //GEvent.addListener(map,'mousemove',function(point) 
        //{ document.getElementById("mouseposition").innerHTML = "lat/long cursor: "+point.toUrlValue(); }); 
        
		GEvent.addListener(map,'mousemove',function(point) 
        {
		var coords = point.toUrlValue(6).split(",");
		var latString = convertLat (coords[0]);
		var lngString = convertLon(coords[1]); 	
		document.getElementById("mouseposition").innerHTML = "Cursor en: "+latString+","+lngString; }); 
        
		
        
//		This is going to google map and sidebar.           
//		for(id in markers) {
//		initializePoint(markers[id]);
//		allTypes[markers[id].stype] = true;
//		}

//		This creates the sort tabs at the top
		/*
        for(stype in allTypes)    {
            initializeSortTab(stype);
        }
		 */
        // paintWP(); No hace falta pintar waypoints fuera de regata
	}
	changeBodyClass('loading', 'standby');
}   

/**
 * changes meteo map on and off
 */
 
 function toggleTraffic() {
      if (toggleState == 1) {
        map.removeOverlay(groundOverlay);
        toggleState = 0;
      } else {
        map.addOverlay(groundOverlay);
        toggleState = 1;
      }
    }

 function toggleTraffic2() {
      if (toggleState2 == 1) {
        map.removeOverlay(groundOverlay2);
        toggleState2 = 0;
      } else {
        map.addOverlay(groundOverlay2);
        toggleState2 = 1;
      }
    }





/**
 * Returns a new GIcon based on a given course
 * @param course {integer} Heading of the boat
 * @return The GIcon with the correspondant image
 * @type GIcon
 * @author Miguel Carlos Mart?nez D?az   
 */
function getIcon(course,query){
	var icon = new GIcon();
	
	icon.iconSize = new GSize(24, 24);
	icon.iconAnchor = new GPoint(12, 12);
	icon.infoWindowAnchor = new GPoint(12, 12);
	var iconCourse = Math.round (course/10); //prepare the course to be used for icons

	if (query == 0)
	{icon.image = "icons/flagicon.png";}
	else {icon.image = "icons/" + iconCourse + ".png";}
	
	return icon;
}
/**
 * Converts latitude in deg to deg, min, sec
 * @param latitude {double} latitude
 * @return a string with deg, min, sec 
 * @type string
 * @author AtlanticSource, Miguel Carlos Mart?nez D?az   
 */
function convertLat (latitude) {

var signo = 1

if (latitude > 0) {var cuad = "N"}
else 
{var cuad = "S";
latitude = latitude * (-1)} 

var latDeg = parseInt (latitude);
var latMin = parseInt ((latitude-latDeg)*60);
var latSec = parseInt ((((latitude-latDeg)*60)-latMin)*60);



textoLat = latDeg + "&deg; " + latMin + "' " + latSec + "&quot; " + cuad; 
//textoLat = cuad + " "+ latDeg +  " g "+ latMin + " m "+ latSec + " s ";
return textoLat;
}
/**
 * Converts longitude in deg to deg, min, sec
 * @param longitude {double} latitude
 * @return a string with deg, min, sec 
 * @type string
 * @author AtlanticSource, Miguel Carlos Mart?nez D?az   
 */
function convertLon (longitude) {

if (longitude > 0) {var cuad = "E"} 
else 
{var cuad = "O";
longitude = longitude * (-1)}

var lonDeg = parseInt (longitude);
var lonMin = parseInt ((longitude-lonDeg)*60);
var lonSec = parseInt ((((longitude-lonDeg)*60)-lonMin)*60); 




textoLon = lonDeg + "&deg; " + lonMin + "' " + lonSec + "&quot; " + cuad;
return textoLon;
} 

/**
 * Generates information tab for a given boat
 * @param markerAux {boatMarker} Boat which extracting the info from
 * @return An array with all the Gtabs 
 * @type Array
 * @author AtlanticSource, Miguel Carlos Mart?nez D?az   
 */

// CUANDO SE INICIE LA REGATA CAMBIAR n/d por  exactamente esto:  '+ markerAux.position + '   '+ markerAux.heading + ' ' + convertLat(markerAux.latitude) + ' ' + convertLon(markerAux.longitude) + ' 
function newInfoTabs(markerAux){
	
	var vel;
	if(markerAux.speed==0){vel="n/d";}else{vel=Math.round(markerAux.speed) + 'nudos';}
	return [
	        new GInfoWindowTab ("Barco", '<span class="style1"><table id="info" width=190px>'
	                        + '<tr><td align="left"><h3>' + markerAux.sname + ' </h3><h5>clase: ' + markerAux.clase + '</h5></td></tr>'
	        		+ '<tr><td align="left" font=arial><img src=images/b' + markerAux.mmsi + '.jpg align="left"></td></tr>'
	        		+ '<tr><td align="left">Rumbo:' + markerAux.heading + 'º</td></tr>'
	        		+ '<tr><td align="left">Velocidad:' + vel + '</td></tr>'
					+ '<tr></tr>'
	        		+ '<tr><td align="left"><h5>Sigue tu barco aquí vía satélite <a href="http://www.atlanticsource.es/?page_id=17&lang_pref=es" target="blank">Contáctanos</a></h5></td></tr>'
	        		+ '</table></span>'),
	        		new GInfoWindowTab ("Skipper", '<span class="style1"><table id="info" width=190px >'
	        		+ '<tr><td><h3>' + markerAux.patron + ' </h3></td></tr>'
	        		+ '<tr><td align="left"><img src=images/p' + markerAux.mmsi + '.jpg align="left"></td></tr>'
	        		+ '<tr><td align="left"><h5>Controla tu barco cómodamente desde tu ordenador<a href="http://www.atlanticsource.es/?page_id=17&lang_pref=es" target="blank">Contáctanos</a></h5></td></tr>'
	        		+ '</table></span>')
	        ];
}

/**
 * Generates a new marker
 * @param xmlMarker {String} XML information corresponding to a boat
 * @return A boatMarker with the ifo contained int he given xmlMarker 
 * @type boatMarker
 * @author AtlanticSource, Miguel Carlos Mart?nez D?az   
 */
function newMarker(xmlMarker){
	//Set boat info
	var markerAux = new Object();
	
    markerAux.position=parseInt(xmlMarker.getAttribute("position"));
	markerAux.mmsi=parseInt(xmlMarker.getAttribute("mmsi"));
	markerAux.mtime=xmlMarker.getAttribute("mtime");
	markerAux.PositionReport=parseInt(xmlMarker.getAttribute("PositionReport"));
	markerAux.latitude=parseFloat(xmlMarker.getAttribute("latitude"));
	markerAux.longitude=parseFloat(xmlMarker.getAttribute("longitude"));
	markerAux.speed=parseFloat(xmlMarker.getAttribute ("speed"));
	markerAux.MilesToEnd=parseFloat(xmlMarker.getAttribute("MilesToEnd"));
	markerAux.dorsal=parseFloat(xmlMarker.getAttribute("dorsal"));
	markerAux.heading=parseFloat(xmlMarker.getAttribute("heading"));
	if (markerAux.heading==511){markerAux.heading=markerAux.course;}
	markerAux.clase=xmlMarker.getAttribute("clase");
	markerAux.width=parseFloat(xmlMarker.getAttribute ("width"));
	markerAux.length=parseFloat(xmlMarker.getAttribute("length"));
	markerAux.sname=xmlMarker.getAttribute("sname");
	markerAux.query=xmlMarker.getAttribute("query");
	markerAux.patron=xmlMarker.getAttribute("patron");
	markerAux.timestamp=xmlMarker.getAttribute("timestamp");
	markerAux.color=xmlMarker.getAttribute("color");
	markerAux.roundedCourse=Math.round (parseFloat(xmlMarker.getAttribute("heading"))/10);
	markerAux.updated=false;
	markerAux.visible=true;
	markerAux.polygon=shipPolygon(
                         markerAux.latitude,
	                     markerAux.longitude,
	                     markerAux.heading,
	                     markerAux.length/2,
	                     markerAux.length/2,
	                     markerAux.width/2,
	                     markerAux.width/2);
	markerAux.gMarker=null;
	markerAux.track=null;
	markerAux.area =markerAux.polygon.getArea();
	markerAux.idMessage =xmlMarker.getAttribute("idMessage");   
	if (markerAux.idMessage == 4){
		var icon = new GIcon();
	icon.iconSize = new GSize(24, 24);
	icon.iconAnchor = new GPoint(12, 12);
	icon.infoWindowAnchor = new GPoint(12, 12);
	icon.image = "icons/bs.png";
	
	}else{
	var icon=getIcon(markerAux.heading,markerAux.query);}
	var point=new GLatLng(xmlMarker.getAttribute("latitude"),xmlMarker.getAttribute("longitude"));
	markerAux.gMarker=new GMarker(point, icon);

	//Add listeners
	GEvent.addListener(markerAux.gMarker,'mouseover',function() {
		markerAux.gMarker.openToolTip(markerAux.sname + '<br />Última actualización: ' + markerAux.mtime);
		if(markerAux.idMessage!=4){markerAux.gMarker.setImage("icons/v/" + markerAux.roundedCourse + ".png");}
		openTooltipMarker=markerAux.gMarker;
	});

	GEvent.addListener(markerAux.gMarker ,'mouseout',function() {
		markerAux.gMarker.closeToolTip();
		if(markerAux.idMessage!=4){markerAux.gMarker.setImage("icons/" + markerAux.roundedCourse + ".png");}
		openTooltipMarker=null;
	});

	GEvent.addListener(markerAux.gMarker ,'infowindowopen',function() {
		if(markerAux.idMessage!=4){markerAux.gMarker.setImage("icons/v/" + markerAux.roundedCourse + ".png");}
		openInfoMarker=markerAux.gMarker;
	});

	GEvent.addListener(markerAux.gMarker ,'infowindowclose',function() {
		if(markerAux.idMessage!=4){markerAux.gMarker.setImage("icons/" + markerAux.roundedCourse + ".png");}
		openInfoMarker=null;
	});

	//DZ: Prepare sidebar element
	var emite="";
	if (markerAux.query == 0){emite = "no emitiendo";} else {emite = "emitiendo";}

	markerAux.listItem = document.createElement('li');
	var listItemLink = markerAux.listItem.appendChild(document.createElement('a'));
	listItemLink.href = "#";
    
    //This is the info that goes into the sidebar, modify carefully.
    listItemLink.innerHTML = '<strong>' + markerAux.sname + ' </strong><span> Clase:'+ markerAux.clase + ', ' + markerAux.patron +  '</span>';
    // modo control de emisión listItemLink2.innerHTML = '<strong>' + markerAux.sname + ' </strong><span>' + markerAux.patron + '</span>';	
	
    //DZ: Prepare sidebar2 element
    markerAux.listItem2 = document.createElement('li');
    var listItemLink2 = markerAux.listItem2.appendChild(document.createElement('a'));
    listItemLink2.href = "#";

var lanza;
if( Math.round((markerAux.MilesToEnd)>6)){lanza=Math.round(markerAux.MilesToEnd);}else{lanza=0;}
var distancia;
if( markerAux.MilesToEnd<9000){distancia = ', Martinique:' + Math.round(lanza) + ' m';}else{distancia=" Retirado";}



	//This is the info that goes into the sidebar, modify carefully.
	listItemLink2.innerHTML = '<strong>' + markerAux.sname + ' </strong><span> Clase:'+ markerAux.clase + distancia +'</span>';
	// modo control de emisión listItemLink.innerHTML = '<strong>' + markerAux.sname + ' </strong><span>' + emite +', '+ markerAux.patron + '</span>';

	//This is the clickable track button
/*	var listItemTracker = document.createElement("input");
	listItemTracker.type = "checkbox";
	listItemTracker.id = "dsd";
	listItemTracker.value = "ver hist?rico";
	listItem.appendChild(listItemTracker);
*/

/**
 * Gets ship historic positions
 * @author Pablo Torres Montero  
 */

	var getShipTrack = function(){ 
		GDownloadUrl("writetrack.php?mmsi="+markerAux.mmsi , function(data) {
		        var positions = [];
		  
	        	var xml = GXml.parse(data);
			var xmlMarkers = xml.documentElement.getElementsByTagName ("markerxml");
			var originalSize=markers.length;
			var markersSearchIndex=0;
			for (var k = 0; k < xmlMarkers.length; k++)  {
				positions[k] = new GLatLng(xmlMarkers[k].getAttribute("latitude"), xmlMarkers[k].getAttribute("longitude"));
        		}
			//markerAux.track = new GPolyline(positions, "#ff0000", 5);
			markerAux.track = new GPolyline(positions, markerAux.color, 5);
		    positions = null; 
            xmlMarkers = null;       
            //markerAux.track= new GPolyline([new GLatLng(39,0),new GLatLng (40,2)], "#ff0000", 5); 
            map.addOverlay(markerAux.track);       
		});
	}

	//This is the information that shows up in the info window, modify carefully.
	var infoTabs = newInfoTabs(markerAux);

	//Function to be triggered when sidebar element clicked   
	var focusPoint = function() {
		map.panTo(markerAux.gMarker.getPoint());
		
		paintTrack();
		markerAux.gMarker.openInfoWindowTabsHtml (infoTabs);
		return false;
	}

	var paintTrack = function(){
			if (markerAux.track== null){
			getShipTrack();
		}else{
			map.removeOverlay(markerAux.track);
			markerAux.track= null;
		}
	}

    
	GEvent.addListener(markerAux.gMarker, 'click', focusPoint);
//	listItemTracker.onclick = paintTrack;
	listItemLink.onclick = focusPoint;
	listItemLink2.onclick = focusPoint;    
	
	markerAux.show = function() { 
		document.getElementById('sidebar-list').appendChild(markerAux.listItem);   
		mgr.addMarker (markerAux.gMarker,1,BOAT_POLYG_ZOOM_LEVEL);
	}

	markerAux.hide = function() {
		document.getElementById('sidebar-list').removeChild(markerAux.listItem);
		mgr.removeMarker(markerAux.gMarker);
	}

	markerAux.hidesidebar = function() {
		document.getElementById('sidebar-list').removeChild(markerAux.listItem);
	}
	markerAux.show();
	
	return markerAux;
}



/**
 * Refreshes a given marker with the info stored in a given xmlMarker
 * @param xmlMarker {String} XML information corresponding to a boat
 * @param markerarker {boatMarker} BoatMarker to be refreshed
 * @return nothing
 * @author Miguel Carlos Mart?nez D?az   
 */

function refreshMarker(xmlMarker, marker){
	marker.mtime=xmlMarker.getAttribute("mtime");
	marker.status=parseInt(xmlMarker.getAttribute("status"));
	marker.stype=xmlMarker.getAttribute("stype");
	marker.latitude=parseFloat(xmlMarker.getAttribute("latitude"));
	marker.longitude=parseFloat(xmlMarker.getAttribute("longitude"));
	marker.speed=parseFloat(xmlMarker.getAttribute ("speed"));
	marker.course=parseFloat(xmlMarker.getAttribute("course"));
	marker.heading=parseFloat(xmlMarker.getAttribute("heading"));
	if (marker.heading==511){marker.heading=marker.course;}
	marker.call=xmlMarker.getAttribute ("call");
	marker.eta=xmlMarker.getAttribute("eta");
	marker.dest=xmlMarker.getAttribute("dest");
	marker.timestamp=xmlMarker.getAttribute ("timestamp");
	marker.roundedCourse=Math.round (parseFloat(xmlMarker.getAttribute("heading"))/10),
	marker.updated=true;
	marker.visible=true;
	marker.polygon=shipPolygon(
                     marker.latitude,
                     marker.longitude,
                     marker.heading,
                     marker.length/2,
                     marker.length/2,
                     marker.width/2,
                     marker.width/2); //Pablo -> by the moment we don't take exact position
   	marker.area =marker.polygon.getArea();
   	marker.idMessage =xmlMarker.getAttribute("idMessage");
	
	mgr.removeMarker(marker.gMarker);
	
	if (marker.idMessage == 4){
		var icon = new GIcon();
	icon.iconSize = new GSize(24, 24);
	icon.iconAnchor = new GPoint(12, 12);
	icon.infoWindowAnchor = new GPoint(12, 12);
	icon.image = "icons/bs.png";
	
	}else{
	var icon=getIcon(marker.heading,markerAux.query);}
	
	var point=new GLatLng(xmlMarker.getAttribute("latitude"),xmlMarker.getAttribute("longitude"));
	marker.gMarker=new GMarker(point, icon);

	GEvent.addListener(marker.gMarker,'mouseover',function() {
		marker.gMarker.openToolTip(marker.sname + '<br />Last Update: ' + marker.mtime);
		if(marker.idMessage!=4){marker.gMarker.setImage("icons/v/" + marker.roundedCourse + ".png");}
		openTooltipMarker=marker.gMarker;
	});

	GEvent.addListener(marker.gMarker ,'mouseout',function() {
		marker.gMarker.closeToolTip();
		if(marker.idMessage!=4){marker.gMarker.setImage("icons/" + marker.roundedCourse + ".png");}
		openTooltipMarker=null;
	});

	GEvent.addListener(marker.gMarker ,'infowindowopen',function() {
		if(marker.idMessage!=4){marker.gMarker.setImage("icons/v/" + marker.roundedCourse + ".png");}
		openInfoMarker=marker.gMarker;
	});

	GEvent.addListener(marker.gMarker ,'infowindowclose',function() {
		if(marker.idMessage!=4){marker.gMarker.setImage("icons/" + marker.roundedCourse + ".png");}
		openInfoMarker=null;
	});

	var infoTabs = newInfoTabs(marker);
	//Function to be triggered when sidebar element clicked   
	var focusPoint = function() {
		map.panTo(marker.gMarker.getPoint());
		marker.gMarker.openInfoWindowTabsHtml (infoTabs);

		return false;
	}

	GEvent.addListener(marker.gMarker, 'click', focusPoint);

	mgr.addMarker(marker.gMarker,1,BOAT_POLYG_ZOOM_LEVEL);
	mgr.refresh();
	
	
}







/**
 * Refreshes the map downloading current positions from the server
 * @author Miguel Carlos Mart?nez D?az   
 */
function refreshMap(){
	GDownloadUrl("writexml.php?mmsi="+mmsi, function (data) {

		var xml = GXml.parse(data);
		var xmlMarkers = xml.documentElement.getElementsByTagName ("markerxml");
		var originalSize=markers.length;
		var markersSearchIndex=0;

        //Remove displayed element before refreshing
        if(openInfoMarker!=null){
            openInfoMarker.closeInfoWindow();
            openInfoMarker=null;
        }
        if(openTooltipMarker!=null){
            openTooltipMarker.closeToolTip();
            openTooltipMarker=null;
        }
        
		for (var k = 0; k < xmlMarkers.length; k++)  {
			var markerIndex=markers.sortedLinearSearch(parseInt(xmlMarkers[k].getAttribute("mmsi")),compBS,markersSearchIndex,originalSize-1);
			if (markerIndex<=0){
				markers.push(newMarker(xmlMarkers[k])); //New boat, add to markers
				markersSearchIndex=-markerIndex;
                /*var listItema = document.createElement('li');
                var listItemLinka = listItema.appendChild(document.createElement('a'));
                listItemLinka.href = "#";
    
                //This is the info that goes into the sidebar, modify carefully.
                listItemLinka.innerHTML = '<strong>' + markers[k].sname + ' </strong><span>' + markers[k].mmsi + ', ' + markers[k].stype + ' Ver Historico</span>';
                
                document.getElementById('sidebar2-list').appendChild(listItema);     */
                //document.getElementById('sidebar2-list').appendChild(markers[k].listItem);   
			}else{
				//Boat already present, update
                map.removeOverlay(markers[markerIndex-1].polygon); //Pablo -> deletes old polygon
				refreshMarker(xmlMarkers[k],markers[markerIndex-1]);
				markersSearchIndex=markerIndex;
			}    
		}
		//if(originalSize!=markers.length)
		//	markers.sort(compSort);
        
        markers.sort(posSort); 
        for (var k = 0; k < markers.length; k++)  {
		    document.getElementById('sidebar2-list').appendChild(markers[k].listItem2);
        }
		//Hide non-updated boats
		for (var k = 0; k < markers.length; k++)  {
		  if(markers[k].visible==false){
		      markers[k].hide;
		  }
		  markers[k].visible=false;
		}
		mgr.refresh(); //Refresh MarkerManager
	});
};

/**
 * Returns the equivalent polygon to a given boat 
 * @param shiplat {float} XML Latitude of the boat
 * @param shiplong {float} Longitude of the boat
 * @param heading {float} heading of the boat
 * @param A {float} Parameter
 * @param B {float} Parameter
 * @param C {float} Parameter
 * @param D {float} Parameter
 * @return {GPolygon} The equivalent polygon
 * @author Pablo Torres  
 */
function shipPolygon(shiplat,shiplong,heading,A,B,C,D){
        // equatorial radius
        
        color = "#ff0000";
        if (A+B+C+D==0){A=5;B=5;C=5;D=5;color = "#00ff00";}
        heading = heading/180*3.14159265;
        equatorialRadius = 6378137;
        // polar radius
        polarRadius = 6356752.314;
    	polarRadius = equatorialRadius*26/21;
    	
        latconv=360/(polarRadius*2*3.14159265);
        longconv=360/(equatorialRadius*2*3.14159265);
        AletaProa=0.2;
        
        
        AletaProa = AletaProa*(A+B);
    
        lat1 = shiplat + ( A * Math.cos(heading) - (D-C)/2 * Math.sin(heading))*latconv;
        long1= shiplong + ( A * Math.sin(heading) + (D-C)/2 * Math.cos(heading))*longconv;
        
        lat2 = shiplat + ( (A - AletaProa) * Math.cos(heading) - D * Math.sin(heading))*latconv;
        long2 = shiplong + ( (A - AletaProa) * Math.sin(heading) + D * Math.cos(heading))*longconv;
        
        lat3 = shiplat + ( - B * Math.cos(heading) - D * Math.sin(heading))*latconv;
        long3 = shiplong + ( - B * Math.sin(heading) + D * Math.cos(heading))*longconv;
        
        lat4 = shiplat + ( - B * Math.cos(heading) + C * Math.sin(heading))*latconv;
        long4 = shiplong + ( - B * Math.sin(heading) - C * Math.cos(heading))*longconv;
        
        lat5 = shiplat + ( (A - AletaProa) * Math.cos(heading) + C * Math.sin(heading))*latconv;
        long5 = shiplong + ( (A - AletaProa) * Math.sin(heading) - C * Math.cos(heading))*longconv;
    
        return new GPolygon([new GLatLng(lat1,long1),new GLatLng(lat2,long2),new GLatLng(lat3,long3),new GLatLng(lat4,long4),new GLatLng(lat5,long5),new GLatLng(lat1,long1)], color, 2, 1, color, 0.2);
    }

/**
 * Object Tooltip constructor
 * @param marker {GMarker} Associated GMarker
 * @param html {String} HTML to be displayed
 * @param width {integer} width of the tooltip
 * @author AtlanticSource   
 */
function ToolTip(marker,html,width) {
	this.html_ = html;
	this.width_ = (width ? width + 'px' : 'auto');
	this.marker_ = marker;
}

ToolTip.prototype = new GOverlay();

/**
 * Initializes the tooltip, associating a GMap and a HTML DIV element
 * @param map {GMap2} Map the tooltip will be displayed on top of
 * @author AtlanticSource   
 */
ToolTip.prototype.initialize = function(map) {
	var div = document.createElement("div");
	div.style.display = 'none';
	map.getPane(G_MAP_FLOAT_PANE).appendChild(div);

	this.map_ = map;
	this.container_ = div;
}

/**
 * Removes the tooltip from the map
 * @author AtlanticSource   
 */
ToolTip.prototype.remove = function() {
	this.container_.parentNode.removeChild(this.container_);
}

/**
 * Creates a copy of the tooltip
 * @return {Tooltip} The new Tooltip object
 * @author AtlanticSource   
 */
ToolTip.prototype.copy = function() {
	return new ToolTip(this.html_);
}

/**
 * Redraws the tooltip
 * @author AtlanticSource   
 */
ToolTip.prototype.redraw = function(force) {
	if (!force) return;

	var pixelLocation = this.map_.fromLatLngToDivPixel (this.marker_.getPoint());
	this.container_.innerHTML = this.html_;
	this.container_.style.position = 'absolute';
	this.container_.style.left = pixelLocation.x + "px";
	this.container_.style.top = pixelLocation.y + "px";
	this.container_.style.width = this.width_;
	this.container_.style.font = 'bold 10px/10px verdana, arial, sans';
	this.container_.style.border = '1px solid black';
	this.container_.style.background = '#CCFFFF';
	this.container_.style.padding = '4px';

//	one line to desired width
	this.container_.style.whiteSpace = 'nowrap';
	if( this.width_ != 'auto') this.container_.style.overflow = 'hidden';
	this.container_.style.display = 'block';
}

/**
 * Associated tooltip
 * @author AtlanticSource   
 */
GMarker.prototype.ToolTipInstance = null;

/**
 * Opens the associated tooltip if present, and if not creates one and opens it
 * @author AtlanticSource   
 */
GMarker.prototype.openToolTip = function(content) {
//	don't show the tool tip if there is acustom info window
	if(this.ToolTipInstance == null) {
		this.ToolTipInstance = new ToolTip(this,content)
		map.addOverlay(this.ToolTipInstance );
	}
}

/**
 * Closes the associated tooltip
 * @author AtlanticSource   
 */
GMarker.prototype.closeToolTip = function() {
	if(this.ToolTipInstance != null) {
		map.removeOverlay(this.ToolTipInstance);
		this.ToolTipInstance = null;
	}
}

/**
 * Returns the height of the window (Browser independent)
 * @return {integer} The height of the window
 * @author AtlanticSource   
 */
function windowHeight() {
//	Standard browsers (Mozilla, Safari, etc.)
	if (self.innerHeight)
		return self.innerHeight;
//	IE 6
	if (document.documentElement && document.documentElement.clientHeight )
		return document.documentElement.clientHeight;
//	IE 5
	if (document.body)
		return document.body.clientHeight;
//	Just in case.
	return 0;
}

//Function to handle the window resizing, may get rid of this later
function handleResize() {
	var height = windowHeight() - document.getElementById('toolbar').offsetHeight - 50;
	document.getElementById('map').style.height = height + 'px';
	document.getElementById ('sidebar').style.height = height + 'px';
}

window.onresize = handleResize;

//Function for opening and closing the side bar
function changeBodyClass(from, to) {
	document.body.className = document.body.className.replace(from, to);
}

//This function allows users to sort their tabs
function initializeSortTab(stype) {
	var listItem = document.createElement('li');
	var listItemLink = listItem.appendChild(document.createElement('a'));

	listItemLink.href = "#";
	listItemLink.innerHTML = stype;
	listItemLink.onclick = function() {

		for(id in markers4) {
			if (markers4[id].stype == stype || 'All' == stype)
				markers4[id].show();
			else
				markers4[id].hide();
		}
		return false;
	}
	document.getElementById('filters').appendChild(listItem);
}



function cleanSidebar () {
	var listItem = document.createElement('li');
	var listItemLink = listItem.appendChild(document.createElement('a'));

	listItemLink.href = "#";
	listItemLink.innerHTML = stype;


	for(id in markers4) {
		markers4[id].hidesidebar();
	}


}

function verificaMmsi (mmsi) {

	var listItem = document.createElement ('li');
	var listItemLink = listItem.appendChild(document.createElement('a'));

	listItemLink.href = "#";
	listItemLink.innerHTML = stype;


	for (h in markers4) {
		markers3 = markers4 [h];
		var mmsiexist = markers3.mmsi;
		if (mmsi == mmsiexist){
			markers4[h].hide ();

		}
		else{}
	}
}

function creaFilterTabs () {
	for(stype in allTypes)    {
		initializeSortTab(stype);
	}
}


//Some start and stop stuff.


