/*+********************************************************************* 
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

(C) 2008 Harald Kirsch (pifpafpuf at gmx dot de)

few minor modifications (C) 2010 Palo TT (palinow at atlas dot cz)
************************************************************************/

function toRadians(angle) {
  return angle*Math.PI/180.0;
}
function greatCircleDistance(point, other) {
  var plon = toRadians(point.lon);
  var plat = toRadians(point.lat);
  var qlon = toRadians(other.lon);
  var qlat = toRadians(other.lat);

  return Math.acos(Math.sin( plat ) * Math.sin(qlat) 
		   + 
		   Math.cos(plat) 
		   *Math.cos(qlat)
		   *Math.cos(toRadians(point.lon-other.lon))) * 6378135;
}
function roundedKm(meter) {
  return (meter*0.001).toFixed(3);
}
//------------------------------------------------------------
/**
 * Define class TrackMarker.
 */
var m = {
  initialize : function(track, lonlat, altitude, options) {
    this.name = "";		// set only explicitly for waypoints
    this.altitude = altitude;
    this.isselected = false;
    this.iswp = false;
    this.track = track;
    this.pop = null		// == track.pop when up for us
    this.map = track.map;
    		// needed by Handler
    var params = [lonlat, this.track.newIcon(), options];
    OpenLayers.Marker.prototype.initialize.apply(this, params);

    this.dragHandler = new OpenLayers.Handler.Drag(this, 
						   {move: this.moveTo, 
						       done: this.moveTo,
						       up: this.deAct});
    this.events.register('mouseover', this, this.mouseOver);
    this.events.register('mouseout', this, this.mouseOut);
    this.events.register('click', this, this.click);    
  },

  deAct : function(evt) {
    this.dragHandler.deactivate();
    if( this.myLine ) {
      this.movePoint(1, this.lonlat);
    }
    if( this.nextMark ) {
      this.nextMark.movePoint(0, this.lonlat);
    }
    this.track.updateTracklengthDisplay();
    gpxTrack.pointmoved = true;  //Palo TT
  },
  mouseOver : function(evt) {
    this.setOpacity(0.6);
    this.dragHandler.activate();
   },
  mouseOut : function(evt) {
    this.setOpacity(1.0);
    if(!this.dragHandler.dragging) {
      this.dragHandler.deactivate();
    }
    this.lock = false;
  },
  moveTo : function(xy) { 
    if( this.pop && this.pop.visible() ) return;
    var xyl = this.map.getLayerPxFromViewPortPx(xy);
    //xyl.x -= 8;
    //xyl.y -= 8;
    OpenLayers.Marker.prototype.moveTo.apply(this, [xyl]);
    this.lock = true;
  },
  click : function(evt) {
  
    if( this.lock ) {
      this.lock = false;
      return false;  //return;
    }
    if( this.pop ) {
      // the popup is up for us, so popdown
      this.track.popdown.call(this.pop);
      return false;  //return;
    }    
    if( evt.ctrlKey ) {
      this.dragHandler.deactivate();
      this.track.delMarker(this);
      this.track.updateTracklengthDisplay();
      return false;  //return;
    }
    if( this.isselected) {
      //if track point is active

     var dmenu=document.getElementById("selectedTP");
     var xy = this.map.getViewPortPxFromLonLat(this.lonlat);
     var WS = windowsize();
     showLayer("selectedTP","block"); 
     var offX=this.icon.size.w/2;
     var offY=-this.icon.size.w/2-dmenu.offsetHeight;
     if (WS[0]-xy.x<parseInt(dmenu.offsetWidth)) offX=-(this.icon.size.w/2)-dmenu.offsetWidth;
     if (xy.y<parseInt(dmenu.offsetHeight)) offY=(this.icon.size.w/2);
     dmenu.style.top=xy.y + offY;
     dmenu.style.left=xy.x + offX;
     return false;  //return;
    } 
    

    this.pop = this.track.pop;
    if( this.pop.targetMarker ) {
      // its up for some other marker, get it down
      this.track.popdown.call(this.pop);
    }
    this.pop.targetMarker = this;
    var pindex= this.pointsFromStart();
    var e = document.getElementById('malti');
    e.value = this.altitude;
    var e = document.getElementById('mname');
    e.value = this.name;
    var e = document.getElementById('pointindex');
    e.value = pindex;
    e.disabled = !this.iswp;
    e = document.getElementById('miswp');
    e.checked = this.iswp;
    e = document.getElementById('trackkm');
    e.innerHTML = pindex + " ; "  +  roundedKm(this.distanceFromStart())
    //this.pop.updateSize();
    var newsz = new OpenLayers.Size(310,120);
    this.pop.setSize(newsz);

    var q = this.map.getExtent().determineQuadrant(this.lonlat);
    var xy = this.map.getLayerPxFromLonLat(this.lonlat);
    if( q.charAt(0)=='b' ) {
      xy.y = xy.y - (this.pop.size.h + this.icon.size.h/2);
    } else {
      xy.y = xy.y + this.icon.size.h/2;
    }
    if( q.charAt(1)=='r' ) {
      xy.x = xy.x - (this.pop.size.w + this.icon.size.w/2);
    } else {
      xy.x = xy.x +  this.icon.size.w/2;
    }
    
    this.pop.moveTo(xy);
    this.pop.show();
    return false;
  },

  // return distance from start of track in meter
  distanceFromStart : function() {
    if( ! this.prevMark ) return 0.0;
    var d = this.prevMark.distanceFromStart();
    var p = gpxTrack.toGrad(this.lonlat);
    var q = gpxTrack.toGrad(this.prevMark.lonlat);
    d = d + greatCircleDistance(p, q);
    return d;
  },

 
  // return distance from start of track in meter
  pointsFromStart : function() {
    if( ! this.prevMark ) return 1;
    var d = this.prevMark.pointsFromStart();
    d++;
    return d;
  },


  movePoint : function(which, lonlat) {
    var p = this.myLine.geometry.components[which];
    p.x = lonlat.lon;
    p.y = lonlat.lat;
    p.move(0,0);
    this.track.vectors.drawFeature(this.myLine);
  }

   
};
TrackMarker = OpenLayers.Class(OpenLayers.Marker, m);








//------------------------------------------------------------
/**
 * Define class GpxTrack
 */
var m = {
  initialize : function(map, options) {
    this.map = map;
    OpenLayers.Control.prototype.initialize.apply(this, [options]);
    map.addControl(this);

    this.visibility = false;
    this.pointmoved = false;
    // create the icon to use as a marker for trackmarks. This icon is
    // reused by each track marker by cloning. 
    this.icon = 
    new OpenLayers.Icon("http://cmaps.gpsteam.eu/pic/redcirc13.png", 
			new OpenLayers.Size(10, 10),
			new OpenLayers.Pixel(-5,-5));
    this.icon.setOpacity(0.8);    

    var e = document.getElementById('popuptemplate');
    var pophtml = e.innerHTML;
    e.innerHTML = "";

    var pop = 
    new OpenLayers.Popup(null,
			 new OpenLayers.LonLat(0,50),
			 new OpenLayers.Size(300,70),
			 pophtml, false, this.popdown);
    var pop = new OpenLayers.Popup(null, null, null, pophtml, 
				   false, this.popdown);
    pop.autoSize = true;
    pop.setBorder("2px dotted grey");
    pop.setBackgroundColor("gold");
    pop.padding = new OpenLayers.Bounds(5, 0, 5, 0);
    this.pop = pop;

    // TODO: change this to lazy init, because otherwise map.setCenter()
    // needs to be called to early
    this.map.addPopup(this.pop); 
    this.pop.hide();

    e = document.getElementById('mname');
    e.onkeypress = this.popKeyPress;

    // initialize the style to use for drawing the lines between tracks
    this.style = OpenLayers.Util.extend(OpenLayers.Feature.Vector.style['default'], {});
    this.style.strokeColor = "gold";
    this.style.strokeColor = "#9e2525";
    this.style.strokeWidth = 3;
    this.style.cursor = "default";
    this.style.hoverStrokeColor = "#bbaaaa";
    this.style.hoverStrokeWidth = 3;

    // initialize the marker counter to generate consecutive default
    // marker names.
    this.mID = 0;

    this.polySelector = 
    new OpenLayers.Handler.Feature(this,
				   this.vectors,
				   {click: this.polygonClick,
				       over: this.polygonOver,
				       out: this.polygonOut});
    this.keyHandler = 
    new OpenLayers.Handler.Keyboard(this,
				    {keyup: this.keyPress});
    this.keyHandler.activate();
  },

  polygonClick : function(feature) {
    this.deactivatePoly();
    var bounds = feature.geometry.getBounds();
    var lonlat = bounds.getCenterLonLat();
    var mark = feature.forMarker;
    var mark2 = mark.prevMark;
    var a1 = mark.altitude;
    var a2 = mark2.altitude;
     //http://stackoverflow.com/questions/825402/why-does-isnan-equal-false
    if ( (isNaN(a1)) || (isNaN(a2)) ||  (a1=='')  || (a2=='') )  
      {var nalt = '';}
      else
      {var nalt = Math.round( (parseFloat(a1) + parseFloat(a2))/2*100 ) / 100;}
        
      
    
    this.setMark(lonlat, mark.prevMark, mark, nalt);
   
  },
  polygonOver : function(feature) {
    this.currentFeature = feature;
    var color = this.style.strokeColor;
    this.style.strokeColor = "#bbaaaa";
    this.vectors.drawFeature(feature, this.style);
    this.style.strokeColor = color;
  },
  polygonOut : function(feature) {
    this.vectors.drawFeature(feature, this.style);
    this.currentFeature = null;
  },

  keyPress : function(evt) {
    if( this.currentFeature ) return;
    if( this.markers.markers.length<2 ) return;
    if( evt.keyCode==65 ) {
      if( !this.polySelector.active ) this.activatePoly();
      else this.deactivatePoly();
    } else if( evt.keyCode==27 ) {
      this.deactivatePoly();
    }
   
  },

  activatePoly : function() {
    this.polySelector.activate();
    setCursor("map", "crosshair");
  },

  deactivatePoly : function() {
    this.currentFeature = null;
    this.polySelector.deactivate();
    setCursor("map", "default");
  },
   
  draw : function() {
    this.map.events.register("click", this, this.setMarkEvent);
  },
  
  newIcon : function() {
    return this.icon.clone();
  },
  popKeyPress : function(evt) {
    if( evt.keyCode!=evt.DOM_VK_RETURN ) return true;

    // ooompf, this function called in HTML context, need global
    // reference because 'this' points the wrong way.
    gpxTrack.nameMarker();
    return false;
  },
  createLine : function(llfrom, llto) {
    var p1 = new OpenLayers.Geometry.Point(llfrom.lon, llfrom.lat);
    var p2 = new OpenLayers.Geometry.Point(llto.lon, llto.lat);
    var geom = new OpenLayers.Geometry.LineString([p1, p2]);
    var v = new OpenLayers.Feature.Vector(geom);
    v.style = this.style;
    this.vectors.addFeatures(v); 
    return v;   
  },
  setMarkEvent : function(evt) {
    if (!(this.visibility)) return;
    //if (!OpenLayers.Event.isLeftClick(evt)) return; //nefunguje v IE
    if (evt.ctrlKey) return;

    //-----Palo TT: IE workaround -problem: IE creates new trackpoint when we dragged existing trackpoint
    //If MapPanning made after new trackpoint creation, next trackpoint dragging is correct.
    if (this.pointmoved) {
       this.pointmoved=false;
       return; 
       }
    //-----
   
    //var pet = new OpenLayers.Pixel(evt.xy.x,evt.xy.y);
    //var lonlat = this.map.getLonLatFromViewPortPx(pet); 
    var lonlat = this.map.getLonLatFromViewPortPx(evt.xy);
  
    var l = this.markers.markers.length;
    var previous = null;
    if( l>0 ) {
      previous = this.markers.markers[l-1];
    }
    this.setMark(lonlat, previous, null, '');
    this.updateTracklengthDisplay();
    
  },
  
  setMark : function(lonlat, previous, next, altitude) {
    var mark = new TrackMarker(this, lonlat, altitude);
    this.markers.addMarker(mark);
    if( previous ) {
      mark.myLine = this.createLine(previous.lonlat, lonlat);
      mark.myLine.forMarker = mark;
      previous.nextMark = mark;
      mark.prevMark = previous;
    }
    if( next ) {
      // get the order right (insert method missing on marker layer)
      var l = this.markers.markers.length-2;
      while( this.markers.markers[l]!=next ) {
	this.markers.markers[l+1] = this.markers.markers[l];
	l -= 1;
      }
      this.markers.markers[l+1] = this.markers.markers[l];
      this.markers.markers[l] = mark;
      mark.nextMark = next;
      next.prevMark = mark;
      if( !next.myLine ) {
	// next was the first and only mark until now
	next.myLine = this.createLine(lonlat, next.lonlat);
      }
      next.movePoint(0, mark.lonlat);
    }
  },
  updateTracklengthDisplay : function() {
    var l = this.markers.markers.length;
    if( l==0 ) {
      hideLayer("tracklength");
    } else {
      showLayer("tracklength", "block");
      var e = document.getElementById("tracklength");
      var lastMarker = this.markers.markers[l-1];
      var distanceFromStart = lastMarker.distanceFromStart();
      e.innerHTML = ""+roundedKm(distanceFromStart)+" km";
    }
  },

  // supports upload of marks. The server sends an array of elements
  // with lon, lat and name to run over
  marksFromList : function(marks) {
    for(i=0; i<marks.length; i++) {
      var minfo = marks[i];             // again a list: lon, lat, name
      var lonlat = new OpenLayers.LonLat(minfo.x,minfo.y);
      var previous = i>0 ? this.markers.markers[i-1] : null;
      this.setMark(lonlat, previous, null, minfo.z);
    }
    this.updateTracklengthDisplay();
  },
  findMarker : function(id) { 
    var markers = this.markers.markers;
    for(var i=0; i<markers.length; i++) {
      if( markers[i].icon.imageDiv.id==id ) return markers[i];
    }
    return null;
  },

  selectMarker : function() {
    var m = this.pop.targetMarker;
    if( !m ) return;
    if (m.isselected)
      {
      m.setUrl("http://cmaps.gpsteam.eu/pic/redcirc13.png");
      m.isselected =false;
      }
    else
      {
      m.setUrl("http://cmaps.gpsteam.eu/pic/greencirc13.png");
      m.isselected =true;
      }
   },

  nameMarker : function() {
    var m = this.pop.targetMarker;
    if( !m ) return;
    e = document.getElementById('malti');
    m.altitude = e.value.trim();

    var e = document.getElementById('miswp');
    if( e.checked ) {
      e = document.getElementById('mname');
      m.name = e.value;
      m.iswp = true;
    } else {
      m.name = "";
      m.iswp = false;
    }
    this.popdown.call(this.pop);
  },
  deleteMarker : function() {
    var m = this.pop.targetMarker;
    if( !m ) return;
    this.popdown.call(this.pop);
    this.delMarker(m);
    this.updateTracklengthDisplay();
  },
  hideMarkerPop : function() {
    this.popdown.call(this.pop);
  },

  popdown : function() {
    // must be called with this==the popup 
    this.targetMarker.pop = null;
    this.targetMarker = null;
    this.hide();
  },
  /**
   * delete marker given by the ID of its icon
   */
  delMarkerByID : function(id) {
    var m = this.findMarker(id);
    if( !m ) return;    
    m.pop.hide();
    this.delMarker(m);
  },

  delMarker : function(m) {
    this.markers.removeMarker(m);
    if( m.prevMark ) {
      m.prevMark.nextMark = m.nextMark;
    }
    if( m.nextMark ) {
      var n = m.nextMark;
      n.prevMark = m.prevMark;
      if( m.prevMark ) {
	n.movePoint(0, m.prevMark.lonlat);
      } else {
	n.myLine.destroy();
	n.myLine = null;
      }
    }
    if( m.myLine ) {
      m.myLine.destroy();
    }
    m.destroy();
  },
  drawMarkerLines : function() {
    //this.pop.hide();
    var markers = this.markers.markers;
    for(var i=1; i<markers.length; i++) {
      markers[i].myLine = this.createLine(markers[i-1].lonlat,markers[i].lonlat);
      markers[i].myLine.forMarker = markers[i];
      //previous.nextMark = mark;
      //mark.prevMark = previous;
      
    }
    //this.mID = 0;
    //this.updateTracklengthDisplay();
  },
  delMarkerLines : function() {
    this.pop.hide();
    var markers = this.markers.markers;
    for(var i=markers.length; i>0; ) {
      --i;
      if(markers[i].myLine)   {
      markers[i].myLine.destroy();
      }
    }
    //this.mID = 0;
    //this.updateTracklengthDisplay();
  },
  clear : function() {
    this.pop.hide();
    var markers = this.markers.markers;
    for(var i=markers.length; i>0; ) {
      this.delMarker(markers[--i]);
    }
    this.mID = 0;
    this.updateTracklengthDisplay();
  },


  setVisibility : function(vv) {
    this.markers.setVisibility(vv);
    this.vectors.setVisibility(vv);
    this.visibility = vv;
  },


  save : function(saveinfo) {
    var markers = this.markers.markers;
    if( markers.length==0 ) {
      if (cmaplang == "svk") msgshow("Nie je definovaná trasa.");
      if (cmaplang == "eng") msgshow("No track defined.");
      return;
    }

    var routename = document.getElementById('filename').value;
      if( routename=="" ) {
       if (cmaplang == "svk") msgshow("Zadaj meno trasy.");
       if (cmaplang == "eng") msgshow("Enter track name.");
      return;
    }
   
   if(saveinfo=="plt") {
     var html="OziExplorer Track Point File Version 2.1<BR>WGS 84<BR>Altitude is in Feet<BR>Reserved 3<BR>";
     html+="0,2,255,"+routename+",0,0,2,255<BR>";
     html+=markers.length+"<BR>"
      for(var i=0; i<markers.length; i++) {
              var m = markers[i];
	      var ll = this.toGrad(m.lonlat);
	      if (m.altitude=='') pp2=-777; else pp2=Math.round(parseFloat(m.altitude)/0.3048);
              wy=Math.round(ll.lat*100000)/100000;
              wx=Math.round(ll.lon*100000)/100000;
	      html+="  "+wy+",  "+wx+",0,  " + pp2 + ",    0.0000000,  ,<BR>";    
      }
 
     e = document.getElementById('filetype');
     e.value="plt"; 
     }
    else {
   


     xmlEl = "trk";
     xmlSegOn = "<trkseg>"
     xmlSegOff = "</trkseg>"
   

   
    

     var html = '<?xml version="1.0"?><BR>'
     + '<gpx version="1.1"<BR>'
     + '  creator="online route/track editor ' + URLpath +'"<BR>'
     + '  xmlns="http://www.topografix.com/GPX/1/1"<BR>'
     + '  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<BR>'
     + '  xsi:schemaLocation="http://www.topografix.com/GPX/1/1<BR>' 
     + '  http://www.topografix.com/GPX/1/1/gpx.xsd"><BR>';
    
     if ((saveinfo=="gpxtrkwpt")||(saveinfo=="gpxwpt")) {
       var wpcount=0;
       for(var i=0; i<markers.length; i++) {
         var m = markers[i];
       	 if( ! m.iswp ) continue;
   	 wpcount++;
         var ll = this.toGrad(m.lonlat);
         if (m.altitude=='') pp2=''; else pp2='<ele>' + Math.round(parseFloat(m.altitude)) + '</ele>';
       	 html = html
	 + '  <wpt lat="'+ll.lat+'" lon="'+ll.lon+'"><BR>'
	 + '    <name>'+m.name+'</name>'  + pp2 + '<BR>'
	 + '  </wpt><BR>';
       }
       html +='</gpx><BR>';
       if (wpcount==0){
         if (cmaplang == "svk") msgshow("Nie sú definované žiadne body (way points)");
         if (cmaplang == "eng") msgshow("No way points defined.");
         return;
        }
  
     }


     if ((saveinfo=="gpxtrk")||(saveinfo=="gpxtrkwpt")) {
       html = html 
       + '  <'+xmlEl+'><BR>'
       + '    <name>'+routename+'</name><BR>'
       + '    '+xmlSegOn+'<BR>';
       for(var i=0; i<markers.length; i++) {
        var m = markers[i];
        var ll = this.toGrad(m.lonlat);
        if (m.altitude=='') pp2=''; else pp2='<ele>' + Math.round(parseFloat(m.altitude)) + '</ele>';
        html += '      <'+xmlEl+'pt lat="'+ll.lat+'" lon="'+ll.lon+'"';
        if( m.name!="" ) {
	 html += '><BR>        <name>'+m.name+'</name>' + pp2 + '<BR>      </'+xmlEl+'pt><BR>';
         } else {
	 html += ">" + pp2 + "</"+xmlEl+"pt><BR>";
         }
       }
       html += '    '+xmlSegOff+'<BR>' + '  </'+xmlEl+'><BR></gpx><BR>';

     }


    e = document.getElementById('filetype');
    e.value="gpx";

   }    
   
   html = html.replace(/</g, '&lt;').replace(/>/g,'&gt;');

   //alert(html);
   
   e = document.getElementById('filecontent');
   e.innerHTML = html; // '<pre>'+html+'</pre>'

	 
   e = document.getElementById('form4');
   e.submit();
  },




  getVertices : function() {
    var markers = this.markers.markers;
    if( markers.length==0 ) 
      {
      return '';
      }
    else
      {
      var vert = new Array();
      for(var i=0; i<markers.length; i++) {
              var m = markers[i];
              var trkpoint = new OpenLayers.Geometry.Point(m.lonlat.lon,m.lonlat.lat,m.altitude);
              vert[i]= trkpoint;
              }

      return vert;
      }   



   },

   

  getArrayWGS : function() {
    var markers = this.markers.markers;
    if( markers.length==0 ) 
      {
      return '';
      }
    else
      {
      var vert = new Array();
      for(var i=0; i<markers.length; i++) {
              var m = markers[i];
              var trkpoint = new OpenLayers.Geometry.Point(m.lonlat.lon,m.lonlat.lat,m.altitude).transform(map.baseLayer.projection,p4326); 
              vert[i] = new Array(trkpoint.x,trkpoint.y,trkpoint.z);
              }

      return vert;
      }   



   },


  getlonlat : function(pIndex) {
   var markers = this.markers.markers;
   var m = markers[pIndex];
   var trkpoint = new OpenLayers.Geometry.Point(m.lonlat.lon,m.lonlat.lat,m.altitude).transform(map.baseLayer.projection,p4326); 
   return trkpoint;
   },



  getPointList : function() {
    var markers = this.markers.markers;
    if( markers.length==0 ) 
      {
      return '';
      }
    else
      {
      var tstring='';
      var delimstr='';
      for(var i=0; i<markers.length; i++) {
              var m = markers[i];
              var trkpoint = new OpenLayers.Geometry.Point(m.lonlat.lon,m.lonlat.lat,m.altitude).transform(map.baseLayer.projection,p4326); 
              tstring = tstring + delimstr + trkpoint.x + ":" +trkpoint.y;
              delimstr='|';
              }

      return tstring;
      }   

   },


  pointCount : function() {
   return this.markers.markers.length;
   },


  setAltitude : function(pIndex,blat) {
   this.markers.markers[pIndex].altitude=blat;
   },
 
  
  readAltitude : function(pIndex) {
   return this.markers.markers[pIndex].altitude;
   }, 
 

  selectPoints : function(bounds) {
    var markers = this.markers.markers;
     for(var i=0; i<markers.length; i++)
       {
        var m = markers[i];
       if (bounds.containsLonLat(m.lonlat))
           {
           if (m.isselected==true)
             {
             m.setUrl("http://cmaps.gpsteam.eu/pic/redcirc13.png");
             m.isselected =false;
             } 
            else
             {
             m.setUrl("http://cmaps.gpsteam.eu/pic/greencirc13.png");
             m.isselected =true;
             }
           }
       }

   
   },


   unselectPoints : function() {
    var markers = this.markers.markers;
     for(var i=0; i<markers.length; i++)
       {
        var m = markers[i];
          if (m.isselected==true)
             {
             m.setUrl("http://cmaps.gpsteam.eu/pic/redcirc13.png");
             m.isselected =false;
             }
       }

   
   },


   deleteMulti : function(select) {             //1 all selected , 2 all unselected , 3 all selected except wpt
    
    var nm;
    var markers = this.markers.markers;
    var m= markers[0];
    nm=m;

    do
    {
    m=nm;
    if (m.nextMark) nm=m.nextMark; else nm=0;
    if ((select==1)&&(m.isselected)) this.delMarker(m); 
    if ((select==2)&&(!m.isselected)) this.delMarker(m);  
    if ((select==3)&&(m.isselected)&&(!m.iswp)) this.delMarker(m); 
    }
    while(nm);
   
   },


    deleteMultiFront : function() {       
    
    var nm;
    var markers = this.markers.markers;
    var m= markers[0];

    while(!(m.isselected))
    {
    if (m.nextMark) nm=m.nextMark; else nm=0;
    this.delMarker(m); 
    m=nm;
    }
   
   
   },


   deleteMultiEnd : function() {       
    
    var nm;
    var markers = this.markers.markers;
    var m= markers[markers.length-1];

    while(!(m.isselected))
    {
    if (m.prevMark) nm=m.prevMark; else nm=0;
    this.delMarker(m);  
    m=nm;
    }
  
   
    },


    
    getList : function(type,reverse,separator) {             //type: 1-full 2-selected only         reverse: true/false     
    var tstring="";
    var markers = this.markers.markers;
      if (!(reverse))
       {
       for(var i=0; i<markers.length; i++) {
          var m = markers[i];
          if (type==1)
           {
           var trkpoint = new OpenLayers.Geometry.Point(m.lonlat.lon,m.lonlat.lat,m.altitude).transform(map.baseLayer.projection,p4326); 
           tstring = tstring +Math.round(trkpoint.x*1000000)/1000000 + separator + Math.round(trkpoint.y*1000000)/1000000  +   separator + trkpoint.z +'\n';
           }
           else if ((type==2)&&(m.isselected))
            {      
            var trkpoint = new OpenLayers.Geometry.Point(m.lonlat.lon,m.lonlat.lat,m.altitude).transform(map.baseLayer.projection,p4326); 
            tstring = tstring + Math.round(trkpoint.x*1000000)/1000000  + separator +Math.round(trkpoint.y*1000000)/1000000 +   separator + trkpoint.z +'\n';
            }
         } 
      }
    else
      {
      for(var i=markers.length-1; i>=0; i--) {
          var m = markers[i];
          if (type==1)
           {
           var trkpoint = new OpenLayers.Geometry.Point(m.lonlat.lon,m.lonlat.lat,m.altitude).transform(map.baseLayer.projection,p4326); 
           tstring = tstring + Math.round(trkpoint.x*1000000)/1000000 + separator + Math.round(trkpoint.y*1000000)/1000000 +   separator + trkpoint.z +'\n';
           }
           else if ((type==2)&&(m.isselected))
            {      
            var trkpoint = new OpenLayers.Geometry.Point(m.lonlat.lon,m.lonlat.lat,m.altitude).transform(map.baseLayer.projection,p4326); 
            tstring = tstring + Math.round(trkpoint.x*1000000)/1000000 + separator + Math.round(trkpoint.y*1000000)/1000000 +   separator + trkpoint.z +'\n';
            }



         } 
      }


   return tstring;
     

   },






  fromGrad : function(lon, lat) {
    var point1 = new OpenLayers.LonLat(lon,lat);
    //alert(point1);
    point1.transform(p4326,map.baseLayer.projection);
    //alert(point1);
    //var xy = {x:lon, y:lat};
    //xy = xy.transform(p4326, p900913, xy);
    return point1;
    //xy.transform(p4326,p900913);
    //alert("fromGrad " + xy);
    //return xy
  },


  toGrad : function(lonlat) {
    var point1 = new OpenLayers.LonLat(lonlat.lon,lonlat.lat);
    //alert(point1);
    point1.transform(map.baseLayer.projection,p4326);
    //alert(point1);
    return point1;

    //var xy = {x: lonlat.lon, y:lonlat.lat};
    //xy = xy.transform(p900913, p4326, xy);
    //return new OpenLayers.LonLat(xy.x, xy.y);
    //xy.transform(p900913,p4326);
    //alert("toGrad " + xy);
    //return xy
  }
  
};
GpxTrack = OpenLayers.Class(OpenLayers.Control, m);
