/**
 * Regatta Timer
 */
const Layout = require("Layout");
const locale = require("locale").name == "system" ? "en" : require("locale").name.substring(0, 2);

// "Anton" bold font
Graphics.prototype.setFontAnton = function(scale) {
  // Actual height 69 (68 - 0)
  g.setFontCustom(atob("[encoded data, 5800 characters]"), 46, atob("EiAnGicnJycnJycnEw=="), 78 + (scale << 8) + (1 << 16));
};

function Regattatimer() {
  return {
    layout: undefined,
    /*
    layouts: {
      idle: function() {
        switch(settings.dial) {
          case "Discs":
            break;
          case "Numeric":
          default:
            break;
        }
      },
      start: function(phase) {
        switch(settings.dial) {
          case "Discs":
            break;
          case "Numeric":
          default:
            break;
        }
      },
      race: function() {
      }
    },
    */
    mode: "idle", // idle, start, race"
    countdown: 300, // 5 minutes
    counter: undefined,
    interval: undefined,
    theme: null,
    themes: {
      "Light": {
        "fgColor": "#000000",
        "bgColor": "#FFFF00",
      },
      "Dark": {
        "fgColor": "#FFFF00",
        "bgColor": "#000000",
      }
    },
    icons: {
      "battery": function() {
        return Graphics.createImage(`
 XXXX
X    X
X XX X
X    X
X XX X
X    X
X XX X
X    X
X XX X
X    X
XXXXXX`);
      },
      "satellites": function() {
        return Graphics.createImage(`
      X
     XoX
    XoX
   XoX
  XoX o   X
 XoX o o XoX
XoX o o XoX
 X   o XoX
      XoX
     XoX
    XoX
     X`);
      },
    },
    settings: Object.assign({
      "debug": false,
      "buzzer": true,
      "dial": "Numeric",
      "gps": true,
      "record": false,
      "theme": "Dark",
    }, require('Storage').readJSON("regattatimer.json", true) || {}),

    translations: Object.assign({
       "de": {
        "speed": "FüG", // Fahrt über Grund
        "speed_unit": "kn"
      },
      "en": {
        "speed": "SOA", // SOA speed of advance
        "speed_unit": "kn"
      }
    }, require('Storage').readJSON("translations.json", true) || {}),

    init: function() {

      if(this.settings.debug) {
        this.countdown = 1;
      }

      this.theme = this.themes[this.settings.theme];

      Bangle.setLCDPower(1);
      Bangle.setLCDTimeout(0);

      // in "idle", "start" or "stoped" mode, a button click (re)starts the countdown
      // in "race" mode, a button click stops the counter
      var onButtonClick = (function(ev) {
        switch(this.mode) {
          case "idle":
            this.resetCounter();
            this.mode = "start";
            this.setLayoutStartMinSec();
            this.startCounter();
            this.interval = setInterval((function() {
              this.startCounter();
            }).bind(this), 1000);
            break;
          case "stoped":
          case "start":
            this.resetCounter();
            this.setLayoutIdle();
            break;
          case "race":
            this.raceCounterStop();
            break;
        }
      }).bind(this);

      setWatch(onButtonClick, BTN1, true);

      this.setLayoutIdle();
    },

    onGPS: function(fix) {
      if(this.mode == "race") {
        if(fix.fix && isFinite(fix.speed)) {
          this.layout.clear(layout.speed);
          this.layout.speed.label = fix.speed.toFixed(2);
          this.layout.render(this.layout.speed);
        }
        this.layout.satellites.label = fix.satellites;
      }
    },

    translate: function(slug) {
      return this.translations[locale][slug];
    },
    // during the start phase, the clock counts down 5 4 1 0 minutes
    // a button click restarts the countdown
    startCounter: function() {

      this.counter --;

      if(this.counter >= 0) {
        var counterMinutes = parseInt(this.counter / 60);

        if(counterMinutes > 0) {
          this.layout.minutes.label = counterMinutes;
          // this.layout.seconds.label = "0".concat(this.counter - counterMinutes * 60).toString().slice(-2);
          this.layout.seconds.label = this.padZeroLeft(this.counter - counterMinutes * 60);
          this.layout.render();
        }
        else {
          this.setLayoutStartSec();
          this.layout.seconds.label = this.counter.toString();
          this.layout.render();
        }
        // this keeps the watch LCD lit up
        g.flip();
      }
      // time is up
      else {
        this.raceCounterStart();
      }
    },
    padZeroLeft: function(str) {
      return str.toString().padStart(2, "0");
    },
    formatTime: function(time) {
      var
        minutes = parseInt(time / 60),
        seconds = time - (minutes * 60);

      return this.padZeroLeft(parseInt(time / 3600)) + ":" + this.padZeroLeft(minutes) + ":" + this.padZeroLeft(seconds);
    },
    raceCounter: function() {

      if(this.counter % 60 == 0) {
        this.layout.clear(this.layout.battery);
        this.layout.battery.label = E.getBattery() + "%";
        this.layout.render(this.layout.battery);
      }

      this.counter ++;

      this.layout.racetime.label = this.formatTime(this.counter);
      this.layout.daytime.label = require("locale").time(new Date(), 1);
      this.layout.render();

      // keeps the watch screen lit up
      g.flip();
    },
    raceCounterStop: function() {
      if(this.interval) {
        clearInterval(this.interval);
        this.interval = undefined;
      }
      this.mode = "stoped";
    },
    raceCounterStart: function() {
      if(this.interval) {
        clearInterval(this.interval);
        this.interval = undefined;
      }

      if(this.settings.buzzer) {
        Bangle.buzz();
      }

      this.counter = 0;
      // switch to race mode
      this.mode = "race";
      this.setLayoutRace();
      this.raceCounter();
      this.interval = setInterval((function() {
        this.raceCounter();
      }).bind(this), 1000);
    },

    resetCounter: function() {
      if(this.interval) {
        clearInterval(this.interval);
        this.interval = undefined;
      }
      this.counter = this.countdown;
    },

    setLayoutIdle: function() {

      g.clear();

      this.mode = "idle";

      this.layout = new Layout({
        type: "v",
        bgCol: this.theme.bgColor,
        c: [
          {
            type: "v",
            c: [
              {type: "txt", font: "Anton", label: "5", col: this.theme.fgColor, id: "minutes", fillx: 1, filly: 1},
              {type: "txt", font: "20%", label: "--:--", col: this.theme.fgColor, id: "daytime", fillx: 1, filly: 1}
            ]
          }
        ]}, {lazy: true});

        this.interval = setInterval((function() {
          this.layout.daytime.label = require("locale").time(new Date(), 1);
          this.layout.render();

          // keeps the watch screen lit up
          g.flip();
        }).bind(this), 1000);
    },
    setLayoutStartMinSec: function() {
      g.clear();

      this.layout = new Layout({
        type: "v",
        bgCol: this.theme.bgColor,
        c: [
          {
            type: "h",
            c: [
              {type: "txt", font: "Anton", label: "4", col: this.theme.fgColor, id: "minutes", fillx: 1, filly: 1},
              {type: "txt", font: "Anton", label: "59", col: this.theme.fgColor, id: "seconds", fillx: 1, filly: 1},
            ]
          }
        ]}, {lazy: true}
      );
    },
    setLayoutStartSec: function() {
      g.clear();

      this.layout = new Layout({
        type: "v",
        bgCol: this.theme.bgColor,
        c:[
          {type: "txt", font: "Anton", label: "", fillx: true, filly: true, col: this.theme.fgColor, id: "seconds"},
        ]}, {lazy: true});
    },
    setLayoutRace: function() {
      g.clear();

      this.layout = new Layout({
        type: "v",
        bgCol: this.theme.bgColor,
        c: [
          {type: "txt", font: "20%", label: "00:00:00", col: this.theme.fgColor, pad: 4, filly: 1, fillx: 1, id: "racetime"},
          {type: "txt", font: "15%", label: "-", col: this.theme.fgColor, pad: 4, filly:1, fillx:1, id: "daytime"},
          // horizontal
          {type: "h", c: [
            {type: "txt", font: "10%", label: this.translate("speed"), col: this.theme.fgColor, pad:4, fillx:1, filly:1},
            {type: "txt", font: "20%", label: "0", col: this.theme.fgColor, pad:4, fillx:1, filly:1, id: "speed"},
            {type: "txt", font: "10%", label: this.translate("speed_unit"), col: this.theme.fgColor, pad:4, fillx:1, filly:1},
          ]},
          {type: "h", c: [
            {type:"img", pad: 2, col: this.theme.fgColor, bgCol: this.theme.bgColor, src: this.icons.satellites()},
            {type: "txt", font: "10%", label: "0", col: this.theme.fgColor, pad: 2, filly:1, id: "satellites"},
            // hacky, use empty element with fillx to push the other elments to the left an right side
            {type: undefined, pad: 2, fillx: 1},
            {type:"img", pad: 2, col: this.theme.fgColor, bgCol: this.theme.bgColor, src: this.icons.battery()},
            {type: "txt", font: "10%", label: "-", col: this.theme.fgColor, pad: 2, filly: 1, id: "battery"},
          ]}
      ]}, {lazy: true});
    }
  };
}

var regattatimer = Regattatimer();
regattatimer.init();

if(regattatimer.settings.gps) {
  Bangle.setGPSPower(1);
  Bangle.on('GPS', regattatimer.onGPS.bind(regattatimer));
}

Bangle.on('kill', function() {
  Bangle.setLCDPower(0);
  Bangle.setLCDTimeout(10);
  /*
  if(regattatimer.settings.gps) {
    Bangle.setGPSPower(0);
  }
  */
});
