//gps, heading
//get permissions
if (navigator.userAgent.match(/(iPod|iPhone|iPad)/)) {
  function requestOrientationPermission() {
    DeviceOrientationEvent
      .requestPermission()
      .then(response => {
        if (response == 'granted') {
          window.addEventListener("deviceorientation", (event) => {
            if (event.webkitCompassHeading) {
              heading = (event.webkitCompassHeading + 180) % 360 - 180; // EAST == +90, WEST == -90
            }
          }, true);
        }
      })
      .catch(console.error)
  }
} else {
  window.addEventListener("deviceorientationabsolute", (event) => {
    heading = ((360 - event.alpha) + 180) % 360 - 180; // EAST == +90, WEST == -90
  }, true);
}

const watchID = navigator.geolocation.watchPosition(
  (position) => {
    latitude = position.coords.latitude;
    longitude = position.coords.longitude;
  },
  (error) => {}, {
    enableHighAccuracy: true,
    maximumAge: 30000,
    timeout: 27000,
  }
);

//distance between 2 locations (lat/lon)
function getDistance(lat1, lon1, lat2, lon2) {
  var R = 6371; // Radius of the earth in km
  var dLat = deg2rad(lat2 - lat1); // deg2rad below
  var dLon = deg2rad(lon2 - lon1);
  var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(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; // Distance in km
  return d;
}

function deg2rad(deg) {
  return deg * (Math.PI / 180)
}

//bearing between 2 locations (lat/lon)

// Converts from degrees to radians.
function toRadians(degrees) {
  return degrees * Math.PI / 180;
};

// Converts from radians to degrees.
function toDegrees(radians) {
  return radians * 180 / Math.PI;
}

//   const y = Math.sin(λ2-λ1) * Math.cos(φ2);
//   const x = Math.cos(φ1)*Math.sin(φ2) -
//             Math.sin(φ1)*Math.cos(φ2)*Math.cos(λ2-λ1);
//   const θ = Math.atan2(y, x);
//   const brng = (θ*180/Math.PI + 360) % 360;  in degrees

function getBearing(startLat, startLng, destLat, destLng) {
  startLat = toRadians(startLat);
  startLng = toRadians(startLng);
  destLat = toRadians(destLat);
  destLng = toRadians(destLng);

  y = Math.sin(destLng - startLng) * Math.cos(destLat);
  x = Math.cos(startLat) * Math.sin(destLat) - Math.sin(startLat) * Math.cos(destLat) * Math.cos(destLng - startLng);
  brng = Math.atan2(y, x);
  brng = toDegrees(brng);
  return (brng + 360) % 360;
}

//promisify -> new Tone.Player
function AudioImport(url) {
  return new Promise((resolve, reject) => {
    var audio = new Tone.Player(url, () => resolve(audio));
  });
}

//promisified 'setTimeout' from https://stackoverflow.com/a/74004853
const asyncTimeout = ms => new Promise(resolve => setTimeout(resolve, ms));

// some p5 tools
class Textline {
  static #lines = 0;
  static #linestep = 20;
  static restart() {
    Textline.#lines = 0;
  }
  static put(t) {
    Textline.#lines = Textline.#lines + 1;
    text(t, 0, Textline.#linestep * Textline.#lines);
  }
}
