//---------------------------- Tyreid ----------------------------//
//
// Bluetooth war-driving app for the Bangle.js 2
//
// TH10111 2023
//

Bangle.loadWidgets();
Bangle.drawWidgets(); // <-- for development only (shouldn't need for a real app)

// Global variables
var gpsFix_flag = 0;
var bt_id_arr = [];
var num_bt_devices = 0;
var running_flag = 0; // 0 = stopped, 1 = running, 2 = paused

// Log file
var file = require("Storage").open("tyreid_log.csv","w");

// Logo
var logo = {
  width : 176, height : 176, bpp : 2,
  buffer : atob("[encoded data, 10328 characters]")
};


//
// Functions
//

function gpsTick(fix) { // GPS fix callback
  //console.log(fix); // print GPS Fix info to console
  if (fix.fix > 0) {
    gpsFix_flag = 1;
  } else {
    gpsFix_flag = 0;
  }
  WIDGETS["widTyreid"].draw(WIDGETS["widTyreid"]); // update widget with gps tick
  Bangle.drawWidgets(); // Not sure why I need this here, but otherwise the widget draws over itself without clearing first!
}

function gpsON() { // Turn GPS on
  Bangle.on('GPS',gpsTick);
  Bangle.setGPSPower(true);
}

function gpsOFF() { // Turn GPS off
  Bangle.setGPSPower(false);
}

function btPacket(packet) { // BT packet callback
  let latest_fix = Bangle.getGPSFix();
  let mac = packet.id.substring(0,17);
  let mac_info = packet.id.substring(18);
  
//  console.log(" ");
//  console.log(packet); // print packet info
  //console.log(mac);
  //console.log(5*latest_fix.hdop); // print latest GPS fix info
//  console.log(" ");
  
  // Compile the values to be stored
  var new_data = [
    latest_fix.time,
    latest_fix.lat,
    latest_fix.lon,
    latest_fix.alt,
    latest_fix.hdop*5,
    packet.name,
    mac,
    mac_info,
    packet.manufacturer,
    packet.rssi,
    packet.services,
    packet.data,
    packet.serviceData,
    packet.manufacturerData
  ];
  // Write data to the file (including a new line)
  file.write(new_data.join(",")+"\n");
  
  if (num_bt_devices < 99) {
    if (!bt_id_arr.includes(mac)) { // if device id has not been recorded
      bt_id_arr[num_bt_devices] = mac; // note the id
      num_bt_devices++; // increment the number of devices found
      // Add the new device to the devices menu, with information...
      //console.log(" ");
      //console.log(mac);
      //console.log(packet.manufacturer);
      //console.log(latest_fix.time);
      //console.log(packet.rssi);
      //console.log(" ");
      // Add the new device to the devices menu, with information...
      device_menu[mac] = () => {
        E.showPrompt([mac,mac_info],{title:"MAC",buttons:{"Ok":true}}).then(function(v){
          E.showPrompt(packet.manufacturer,{title:"Manufacturer",buttons:{"Ok":true}}).then(function(v){
            E.showPrompt(latest_fix.time,{title:"First Seen",buttons:{"Ok":true}}).then(function(v){
              E.showPrompt(packet.rssi,{title:"RSSI",buttons:{"Ok":true}}).then(function(v){
                E.showMenu(device_menu);
              });
            });
          });
        });
      };
      }
  }
}

function headings() { // Add headings to the file  
  // Compile the values to be stored
  var new_data = [
    "Time",
    "Latitude",
    "Longitude",
    "Altitude",
    "Accuracy",
    "Name",
    "MAC",
    "MAC Info",
    "Manufacturer",
    "RSSI",
    "Services",
    "Data",
    "Service Data",
    "Manufacturer Data"
  ];
  // Write data to the file (including a new line)
  file.write(new_data.join(",")+"\n");
}

function btON() { // Turn Bluetooth on
  NRF.setScan(btPacket);
}

function btOFF() { // Turn Bluetooth off
  NRF.setScan();
}

function start() { // Start the application
  bt_id_arr = [];
  headings();
  num_bt_devices = 0;
  btON();
  running_flag = 1;
  E.showMenu(running_menu);
}

function exit() { // Exit the application
  gpsOFF();
  btOFF();
  running_flag = 0;
  load();
}

function pause() { // Pause the application
  btOFF();
  running_flag = 2;
  //console.log(bt_id_arr);
  E.showMenu(pause_menu);
}

function resume() { // Continue after pause
  btON();
  running_flag = 1;
  E.showMenu(running_menu);
}

function marker() { // add a marker packet to the log
  let latest_fix = Bangle.getGPSFix();
  
//  console.log(" ");
//  console.log("MARKER"); // print packet info
//  console.log(" ");
  
  // Compile the values to be stored
  var new_data = [
    latest_fix.time,
    latest_fix.lat,
    latest_fix.lon,
    latest_fix.alt,
    latest_fix.hdop,
    "MARKER"
  ];
  
  // Write data to the file (including a new line)
  file.write(new_data.join(",")+"\n");
  
  // Indicate that the marker has been added
  E.showMessage("Marker Added.");
  
  // Back to the menu
  if (running_flag == 0) {
    E.showMenu(init_menu);
  } else if (running_flag == 1) {
    E.showMenu(running_menu);
  } else {
    E.showMenu(pause_menu);
  }
}

setWatch(() => { // If the button is pressed, then add a marker
  marker();
}, BTN1, {repeat:true});

WIDGETS["widTyreid"]={
		area:"tl", // tl (top left), tr (top right), bl (bottom left), br (bottom right)
		width: 24, // width of the widget
		draw: function() {
      let disp_dev_val = "-";

      if (num_bt_devices < 99) {
        disp_dev_val = num_bt_devices.toString();
      } else {
        disp_dev_val = "99+";
      }

      g.setFont("6x8",3);
      if (gpsFix_flag == 1) {
        g.setColor(0,1,0).drawString(disp_dev_val, this.x+24/2, this.y); // green
      } else {
        g.setColor(1,0,0).drawString(disp_dev_val, this.x+24/2, this.y); // red
      }
      }
};


let init_menu = {
  "": { "title": "Tyreid" },
  "Start":  function() { start(); },
  "Marker": function() { marker(); },
  "Exit":   function() { exit(); },
};

let running_menu = {
  "": { "title": "[Running]" },
  "Pause":  function() { pause(); },
  "Marker": function() { marker(); },
  "Exit":   function() { exit(); },
};

let pause_menu = {
  "": { "title": "[Paused]" },
  "Continue":  function() { resume(); },
  "Devices":   function() { E.showMenu(device_menu); },
  "Marker": function() { marker(); },
  "Exit":   function() { exit(); },
};

let device_menu = {
  "": { "title": "Devices:" },
  "Back":  function() { 
    if (running_flag == 0) {
      E.showMenu(init_menu);
    } else if (running_flag == 1) {
      E.showMenu(running_menu);
    } else {
      E.showMenu(pause_menu);
    }
  },
};


// Main
gpsON(); // turn GPS on straight away to start trying for a fix
g.setColor(1,1,1).fillRect(0,0,176,176);
g.drawImage(logo,0,0); // splash screen
// 2sec wait before starting initial menu
setTimeout(function () {
  E.showMenu(init_menu);
}, 2*1000);


