//Ship tracking script for Atlantic Source network


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

var tipos = Array();

var markers4 = [];
var markers=[];
var allTypes = { 'All':[] };
var stype;
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 slat = 27.5; //latitud centro del mapa
var slon = -35.5; //longitud centro del mapa
var zlvl = 4; //zoom centro

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


//-------------------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.atposition.com/atlanticsource/sat/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.No aplica
	//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"));
		var topLeft = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(50,80));
		//var mapZoomControl = new GSmallZoomControl();
		var mapZoomControl = new GSmallMapControl();

        
        map.addControl(mapZoomControl, topLeft);

		//map.addControl(new GLargeMapControl());
		//map.addControl(new GMapTypeControl());
		//map.addControl(new GOverviewMapControl());
		map.addControl(new PromoControl());
		map.enableScrollWheelZoom();
		map.setCenter(new GLatLng(slat, slon), zlvl, G_PHYSICAL_MAP);
		//GEvent.addListener(map,'zoomend',newZoom);
        //creacion de mini-icono
        
        // Create our "tiny" marker icon
        var tinyIcon = new GIcon();
        tinyIcon.image = "http://labs.google.com/ridefinder/images/mm_20_red.png";
        tinyIcon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
        tinyIcon.iconSize = new GSize(12, 20);
        tinyIcon.shadowSize = new GSize(22, 20);
        tinyIcon.iconAnchor = new GPoint(6, 20);
        tinyIcon.infoWindowAnchor = new GPoint(5, 1);

        // Set up our GMarkerOptions object literal
        markerOptions = { icon:tinyIcon };
        
        
        //Grib data loader
          var windData = new GribDataLoader(map);
        windData.setEnablerButton(document.getElementById("windDataEnablerButton"));
        windData.setDateInfoContainer(document.getElementById("windCurrentDateDisplayer"));  
        windData.setLoadingMask(document.getElementById("loadingDiv"));
        // windData.dropModifier=1;
	    // windData.usePlaceMarks=false;
	    windData.setArrowsMode("images");
        //   windData.Init();


		//waypoints
		
		 //Salida - Puerto Sherry
		 var latwp = 36.576033;
         var lonwp =  -6.256;
		 var marker = new GMarker(new GLatLng(latwp, lonwp));
         GEvent.addListener(marker, "click", function() {
         var html = '9 de enero 2008:<br/>Salida desde Puerto Sherry<br/>Puede hacer zoom sobre el mapa y ver los barcos <br/><img src="http://www.puertosherry.com/imagenes/nautico/ctecnicas1.jpg" height="156" width="234" /> <br/>'+convertLat(latwp)+','+convertLon(lonwp);
           marker.openInfoWindowHtml(html);
         });
         map.addOverlay(marker);
         
         //Boya Los Cochinos
         var latwp = 36.553583;
         var lonwp =  -6.320050;
         var marker1 = new GMarker(new GLatLng(latwp, lonwp),markerOptions);
         GEvent.addListener(marker1, "click", function() {
         var html1 = 'Boya Los Cochinos<br/>Puede hacer zoom sobre el mapa y ver los barcos <br/> <br/>'+convertLat(latwp)+','+convertLon(lonwp);
         marker1.openInfoWindowHtml(html1);
         });
         map.addOverlay(marker1);
         
         //Lanzarote Norte
         var latwp = 29.312833;
         var lonwp = -13.258183;
         var marker2 = new GMarker(new GLatLng(latwp, lonwp),markerOptions);
         GEvent.addListener(marker2, "click", function() {
         var html2 = 'Lanzarote Norte <br/>'+convertLat(latwp)+','+convertLon(lonwp);
         marker2.openInfoWindowHtml(html2);
         });
         map.addOverlay(marker2);

         
         //Lanzarote Centro
         var latwp = 28.918500;
         var lonwp = -13.518767;
         var marker3 = new GMarker(new GLatLng(latwp, lonwp),markerOptions);
         GEvent.addListener(marker3, "click", function() {
         var html3 = 'Lanzarote Centro <br/>'+convertLat(latwp)+','+convertLon(lonwp);
         marker3.openInfoWindowHtml(html3);
         });
         map.addOverlay(marker3);
         
         //Marina Rubicón
         var latwp = 28.820700;
         var lonwp = -13.800300;
         var marker4 = new GMarker(new GLatLng(latwp, lonwp));
         GEvent.addListener(marker4, "click", function() {
         var html4 = 'Parada (opcional) en <a href="http://www.marinarubicon.com/esp/index.html">Marina Rubicón</a>.<br>Distancia desde la Salida:618 millas<br><img src="http://www.marinarubicon.com/pic/full2/slideshow003.jpg" height="200" width="250" /> <br/>'+convertLat(latwp)+','+convertLon(lonwp);
         marker4.openInfoWindowHtml(html4);
         });
         map.addOverlay(marker4);
         
         //La Palma Norte
         var latwp = 28.875483;
         var lonwp = -17.844550;
         var marker5 = new GMarker(new GLatLng(latwp,lonwp),markerOptions);
         GEvent.addListener(marker5, "click", function() {
         var html5 = 'Palma Norte <br/>'+convertLat(latwp)+','+convertLon(lonwp);
         marker5.openInfoWindowHtml(html5);
         });
         map.addOverlay(marker5);
         
         //Puerto Rico-Mona
         var latwp = 18.531583;
         var lonwp = -67.178033;
         var marker6 = new GMarker(new GLatLng(latwp, lonwp),markerOptions);
         GEvent.addListener(marker6, "click", function() {
         var html6 = 'Puerto Rico-Mona <br/>'+convertLat(latwp)+','+convertLon(lonwp);
         marker6.openInfoWindowHtml(html6);
         });
         map.addOverlay(marker6);
         
         //Santo Domingo-Sur
         var latwp = 18.058450;
         var lonwp = -68.611483;
         var marker7 = new GMarker(new GLatLng(latwp, lonwp),markerOptions);
         GEvent.addListener(marker7, "click", function() {
         var html7 = 'Santo Domingo-Sur <br/>'+convertLat(latwp)+','+convertLon(lonwp);
         marker7.openInfoWindowHtml(html7);
         });
         map.addOverlay(marker7);
         
         //Santo Domingo
         var latwp = 18.461350;
         var lonwp = -69.888783;
         var marker8 = new GMarker(new GLatLng(latwp, lonwp));
         GEvent.addListener(marker8, "click", function() {
         var html8 = 'Llegada a <a href="http://es.wikipedia.org/wiki/Rep%C3%BAblica_Dominicana">Santo Domingo</a><br>Distancia desde la Salida:3.740 millas<br><img src="http://upload.wikimedia.org/wikipedia/commons/thumb/6/62/Playa_Bavaro.JPG/250px-Playa_Bavaro.JPG" height="210" width="210" /> <br/>'+convertLat(latwp)+','+convertLon(lonwp);
         marker8.openInfoWindowHtml(html8);
         });
         map.addOverlay(marker8);
         

		

		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();
	}
	changeBodyClass('loading', 'standby');



      
       

}   



/**
 * 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"><strong>' + markerAux.sname + '</td></tr><tr><td><img src=images/b' + markerAux.mmsi + '.jpg align="left"></td><td> </strong>Clase: ' + markerAux.clase + '<br/>Rumbo:' + markerAux.heading +  'º<br/>Velocidad:' + vel  + '<br/>Millas hasta Santo Domingo:  ' + Math.round(markerAux.MilesToEnd) + '<br/>Última actualización hora UTC: ' + markerAux.mtime+'</td></tr>'
	        		+ '<tr><td align="left"><strong>¿Quieres instalar un sistema de seguimiento en tu barco?<a href="http://www.atlantic-source.com/contact" target="blank">Contáctanos</a></strong></td></tr>'
	        		+ '</table></span>'),
	        		new GInfoWindowTab ("Skipper", '<span class="style1"><table id="info" width=190px >'
	        		+ '<tr><td><strong>' + markerAux.patron + ' </strong></td></tr>'
	        		+ '<tr><td align="left"><img src=images/p' + markerAux.mmsi + '.jpg align="left"></td></tr>'
	        		+ '<tr><td align="left"><strong>¿Quieres instalar un sistema de seguimiento en tu barco?<a href="http://www.atlantic-source.com/contact" target="blank">Contáctanos</a></strong></td></tr>'
	        		+ '</table></span>')
	        ];
}

// variables: poner el + markerAux.MilesToEnd

/**
 * 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 hora UTC: ' + 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 = '<img src=images/b' + markerAux.mmsi + 's.jpg align="left"><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>';	
	
	
	// variable eliminada: ' + markerAux.position + 'º, 
	
    //DZ: Prepare sidebar2 element
    markerAux.listItem2 = document.createElement('li');
    var listItemLink2 = markerAux.listItem2.appendChild(document.createElement('a'));
    listItemLink2.href = "#";

var lanza;
//calcula distancia a lanzarote if( Math.round((markerAux.MilesToEnd)-2747.9>0)){lanza=Math.round((markerAux.MilesToEnd)-2747.9);}else{lanza=0;}
var distancia;
if( markerAux.PositionReport==1){distancia = ', Santo Domingo: ' + Math.round(markerAux.MilesToEnd) + ' m';}else{distancia=' No compite, Santo Domingo: ' + Math.round(markerAux.MilesToEnd);}



	//This is the info that goes into the sidebar, modify carefully.
	listItemLink2.innerHTML = '<strong>' + markerAux.sname + ' </strong><span>' + markerAux.position + 'º, 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", 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()  - 50; // eliminado "- document.getElementById('toolbar').offsetHeight"
	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);
	}
}






