/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */


var lastGpsUpdateTimestamp = 0;

var userPosition = {
    coords: {
        latitude: 0.0,
        longitude: 0.0,
        accuracy: 999999
    }
};

var geoerrorcount = 0;

var mapLocationControlStarted = false;

if ("geolocation" in navigator) {
    navigator.geolocation.watchPosition(function (position) {
        userPosition = position;
        if (mapLocationControlStarted) {
            //setMapLocation(position.coords.latitude, position.coords.longitude);
            // Don't refresh at an interval less than ten seconds
            var currentTimestamp = Math.floor(Date.now() / 1000);
            if (lastGpsUpdateTimestamp < (currentTimestamp - 10)) {
                updateDistances(position.coords.latitude, position.coords.longitude);
                if (map != null) {
                    map.updatePackageLayer(packages);
                }

                lastGpsUpdateTimestamp = currentTimestamp;
                for (var i = 0; i < packages.length; i++) {
                    if (packages[i].distance * 1 < localStorage.getItem("alertradius") * 1) {

                        if (packages[i].lastAlert > currentTimestamp - 30) {
                            continue;
                        }

                        if (packages[i].delivered) {
                            continue;
                        }

                        playSound("alert");

                        packages[i].lastAlert = currentTimestamp;
                    }
                }
            }
        } else {
            if (map != null) {
                map.locateControl.start();
                mapLocationControlStarted = true;
            }
        }
    }, function (err) {
        if (typeof error == "function") {
            error(err.message);
        }
    }, {
        enableHighAccuracy: true,
        timeout: 5000,
        maximumAge: 0
    });
} else {
    geoerrorcount++;
    console.log("Geolocation error #" + geoerrorcount + ": ", error);
    // Stop showing error toasts if they're happening a lot
    if (geoerrorcount <= 3) {
        app.toast.show({
            text: '<i class="fas fa-compass"></i> ' + error,
            position: "bottom",
            destroyOnClose: true,
            closeTimeout: 1000 * 3
        });
    }
}

/**
 * Calculate distance between two GPS points using Vincenty Formula.
 *
 * From Aman Singh https://stackoverflow.com/q/30536869
 *
 * @param {type} lat1
 * @param {type} lon1
 * @param {type} lat2
 * @param {type} lon2
 * @returns {Number} distance in meters
 */
function getDistance(lat1, lon1, lat2, lon2) {

    var toRad = function (value) {
        return value * Math.PI / 180;
    }

    var a = 6378137, b = 6356752.314245, f = 1 / 298.257223563;
    var L = toRad(lon2 - lon1);
    var U1 = Math.atan((1 - f) * Math.tan(toRad(lat1)));
    var U2 = Math.atan((1 - f) * Math.tan(toRad(lat2)));
    var sinU1 = Math.sin(U1), cosU1 = Math.cos(U1);
    var sinU2 = Math.sin(U2), cosU2 = Math.cos(U2);

    var lambda = L, lambdaP, iterLimit = 100;
    do
    {
        var sinLambda = Math.sin(lambda), cosLambda = Math.cos(lambda);
        var sinSigma = Math.sqrt((cosU2 * sinLambda) * (cosU2 * sinLambda) + (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda) * (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda));
        if (sinSigma == 0)
            return 0;

        var cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda;
        var sigma = Math.atan2(sinSigma, cosSigma);
        var sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma;
        var cosSqAlpha = 1 - sinAlpha * sinAlpha;
        var cos2SigmaM = cosSigma - 2 * sinU1 * sinU2 / cosSqAlpha;
        if (isNaN(cos2SigmaM))
            cos2SigmaM = 0;
        var C = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha));
        lambdaP = lambda;
        lambda = L + (1 - C) * f * sinAlpha * (sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM)));
    } while (Math.abs(lambda - lambdaP) > 1e-12 && --iterLimit > 0);

    if (iterLimit == 0)
        return NaN

    var uSq = cosSqAlpha * (a * a - b * b) / (b * b);
    var A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq)));
    var B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq)));
    var deltaSigma = B * sinSigma * (cos2SigmaM + B / 4 * (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) - B / 6 * cos2SigmaM * (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 * cos2SigmaM * cos2SigmaM)));
    var s = b * A * (sigma - deltaSigma);
    return s;
}