JSVL 						= JSVL 						|| {};


JSVL.LATLON = {


    EARTHRADIUS:{
        KM:6371.0 // earth's mean radius in km
    },
    PIRADIANS:(Math.PI / 180),
    PIDEGREE: (180 / Math.PI),
    toRadians : function(degree) {

        return   degree * this.PIRADIANS;
    },
    toDegree : function(radians) {
      
        return radians * this.PIDEGREE;
    },
    toBearing : function(radians) {     // convert radians to degrees (as bearing: 0...360)
        var deg = JSVL.LATLON.toDegree(radians);
        deg = deg + 360;
        deg = deg % 360;
      return deg;
    },
    getDestinationPoint : function(lat,lon, bearing, distance,earthRadius) {

        var R =  earthRadius || JSVL.LATLON.EARTHRADIUS.KM ;
        var lat1 = JSVL.LATLON.toRadians(lat);
        var lon1 = JSVL.LATLON.toRadians(lon);
        var brng = JSVL.LATLON.toRadians(bearing);
        var d    = distance;

        var dR = d/R;

        var cosDR = Math.cos(dR) ;
        var sinDR = Math.sin(dR) ;

        var cosLAT1 = Math.cos(lat1) ;
        var sinLAT1 = Math.sin(lat1) ;

        var cosBrng = Math.cos(brng);
        var sinBrng = Math.sin(brng);

        var lat2 = Math.asin(  (sinLAT1*cosDR) +
                              ((cosLAT1*sinDR)*cosBrng ) ) ;

     
        var sinLAT2 = Math.sin(lat2) ;



        var lon2 = lon1 + Math.atan2(sinBrng*sinDR*cosLAT1,
                                     cosDR-(sinLAT1*sinLAT2));

        lon2 = ((lon2+Math.PI)%(2*Math.PI)) - Math.PI;  // normalise to -180...+180

        if (isNaN(lat2) || isNaN(lon2)) return null;

        lat2 = JSVL.LATLON.toDegree(lat2);
        lon2 = JSVL.LATLON.toDegree(lon2);

        return  { LAT:lat2, LON:lon2 };
    },


    getDistanceCosineLaw : function(lat1, lon1, lat2, lon2,earthRadius) {

      var R    = earthRadius || JSVL.LATLON.EARTHRADIUS.KM ; // earth's mean radius in km
      var dLat = JSVL.LATLON.toRadians(lat2-lat1);
      var dLon = JSVL.LATLON.toRadians(lon2-lon1);
      lat1 = JSVL.LATLON.toRadians(lat1)
      lat2 = JSVL.LATLON.toRadians(lat2);
       var d = Math.acos(Math.sin(lat1))*Math.sin(lat2) +
               Math.cos(lat1)*Math.cos(lat2)*Math.cos(dLon) * R;
      return d;
    },
     getDistanceHaversine : function(lat1, lon1, lat2, lon2,earthRadius) {
      var R    = earthRadius || JSVL.LATLON.EARTHRADIUS.KM ; // earth's mean radius in km
      var dLat  = JSVL.LATLON.toRadians(lat2-lat1);
      var dLon  = JSVL.LATLON.toRadians(lon2-lon1);
      lat1 = JSVL.LATLON.toRadians(lat1)
      lat2 = JSVL.LATLON.toRadians(lat2);

      var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
              Math.cos(lat1) * Math.cos(lat2) *
              Math.sin(dLon/2) * Math.sin(dLon/2);
      var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
      var d = R * c;
      return d;
    },

    getCirclePoints : function(lat,lon, circleRadius, earthRadius) {

                var R =  earthRadius || JSVL.LATLON.EARTHRADIUS.KM ;
                var cR   = circleRadius || 20.0;
                var lat1 = JSVL.LATLON.toRadians(lat);
                var lon1 = JSVL.LATLON.toRadians(lon);



                var DIST = cR / R; // d = angular distance covered on earth's surface



                var cosDIST = Math.cos(DIST);
                var sinDIST = Math.sin(DIST);

                var cosLAT1 = Math.cos(lat1);
                var sinLAT1 = Math.sin(lat1);




                var locs = new Array();
                for (var x = 0; x <= 360; x++)
                {

                    var p2 = {};
                    var brng   = JSVL.LATLON.toRadians(x);
                    var cosBrng = Math.cos(brng);
                    var sinBrng = Math.sin(brng);

                    p2.LAT = Math.asin(sinLAT1*cosDIST + cosLAT1*sinDIST*cosBrng);
                    p2.LON = (lon1 + Math.atan2(sinBrng*sinDIST*cosLAT1, cosDIST-sinLAT1*Math.sin(p2.LAT))) ;

                    p2.LAT = JSVL.LATLON.toDegree(p2.LAT);
                    p2.LON = JSVL.LATLON.toDegree(p2.LON );
                    locs.push(p2);

                }

                return locs;


            }




};


(function (){

    

})();


