Bangle.loadWidgets();

Graphics.prototype.setFontDoto = function(scale) {
  // Actual height 40 (39 - 0)
  // 1 BPP
  return this.setFontCustom(
    E.toString(require('heatshrink').decompress(atob('[encoded data, 4596 characters]'))),
    32,
    atob("GAwQFBQUFAwQEBQUEBQQFBQUFBQUFBQUFBQQEBQUFBQUFBQUFBQUFBQQFBQUFBQUFBQUFBQUFBQUFBQQFBAUFBAUFBQUFBQUFBAUFBAUFBQUFBQUFBQUFBQUFBQMFBQAFgsQACcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADBQUExQGFBAUFBgXABQUEBYNDBAUFAwQCxQYHBwdFBQUFBQUFBQUFBQUFBAQEBAUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUEBAQEBQUFBQUFBQUFBQUFBQUFBQ="),
    40+(scale<<8)+(1<<16)
  );
};

// Load settings
const SETTINGS = 'scrolly.json';
let settings = Object.assign({
  maxBright: true,
  doNotDim: true,
  speed: 50,
  rotate: 0,
  countdown: true,
  lastText: '',
  rememberText: true
}, require('Storage').readJSON(SETTINGS, true) || {});

let x;
let scrollInterval, countdownInterval;
let countdownNum;
let text = settings.lastText;
let originalOptions = Bangle.getOptions();
let brightness = require('Storage').readJSON('setting.json').brightness;

// Main interface
var Layout = require("Layout");
var layout = new Layout( {
  type: 'v', c: [
    { // Text area
      type: 'txt',
      font: '6x8:2',
      label: text ? text : 'Enter text...', // Show prompt if text not set
      col: text ? g.theme.fg2 : '#555', // Grey text if prompt shown
      id: 'text',
      wrap: true,
      height: Bangle.appRect.h - 52, // Icons are 32px, padding 10px top and bottom
      width: g.getWidth(),
      valign:0,
      cb: l=> editText() // Tapping the text area triggers the same editor as the pen icon
    },
    {
      type: 'h', c: [
        { // Edit icon
          type: 'img',
          pad: 10,
          src: require("heatshrink").decompress(atob("kEg4kA///6f8gH41VStP6gGYBYPv2dV1uyykkvOe+/LrVNteW2sA3Bc4hnM4APM5mY5geM51m3ogL5mGs1r7geK48bswgL5lxiO2EAJBIDwMRiIgC3ggHDwURilGs25B4weDiNCkgPIDwkikV7xgeLkUvrpPGDw311guFDw9aD0sMyIeMB4O2DxgPCsIeLgHNW4MSDxUA5IPBsgeKgHOB4Nmp4eJgHLB4W/DxMM522s279PDDxEM7HuxPc5kwB5Pd5nMFhAPDDZQAyA=")),
          cb: l=> editText()
        },
        { // Settings icon
          type: 'img',
          pad: 10,
          src: require("heatshrink").decompress(atob("kEg4UA///6ec1VSqOMEzUVqoHFqoHUisBA4NAiglDr/1qtUCofq1YZDqte1Wq2oZBDoNaA4OlA4dqA4OpqtQA4Pq1EqEANAF4Oq0EK1QvCguqwEC1VQA4wPKD4IPFF4InBF4MAH4xHCvQHB1oHDL4ofBq4HB6pvDqt//p/DisFR4QHCV64HJiolEAAw=")), 
          cb: l=> showSettings()
        },
        { // Scroll icon
          type: 'img',
          pad: 10,
          src: require("heatshrink").decompress(atob("kEg4UB8EH/4AC+mnqoAQqAgBA4goCgoGCqgxDA4VAA4cVCwgYEA4kBDwogCGoMD+AHFgWsFAYHC1XAA4Q2BA4OwA42oA4wYCgoHEDAIHNC42rMAQHD0AvGI4ZPCCwQHDgYWCM4J3HA4qHBS5CnHYwTIFDwoQECwTJDAwoAFA")),
          id: 'scrollBtn', 
          cb: l=>{
            if (text) {
              scrollText();
            } else {
              E.showAlert('No text to scroll').then(() => {
                layout.setUI();
                layout.render();
              });
            }
          }
        },
      ]
    }
  ]
}, {back: load});

// Display scrolling text
function scrollText() {
  require("widget_utils").hide();

  Bangle.setUI({
    mode:"custom",
    btn: () => { // Button returns to main interface
      if (scrollInterval) // Stop scroll
        clearInterval(scrollInterval);
      if (countdownInterval) // Stop countdown
        clearInterval(countdownInterval);

      // Reset screen to original settings
      g.setRotation(0);
      Bangle.setOptions(originalOptions);
      Bangle.setLCDBrightness(brightness);

      // Draw the main interface
      require("widget_utils").show();
      g.clearRect(Bangle.appRect);
      layout.setUI();
      layout.render();
    }
  });

  // Setup screen
  if (settings.doNotDim) { // Don't lock or turn off the backlight while scrolling
    Bangle.setOptions({backlightTimeout: 0, lockTimeout: 0});
    Bangle.setBacklight(1);
  } else { // For some reason the screen locking resets the font style and alignment, so don't allow this to happen while scrolling
    Bangle.setOptions({lockTimeout: 0});
  }
  if (settings.maxBright) {
    Bangle.setLCDBrightness(1);
  }
  g.setRotation(settings.rotate);

  g.setFontDoto(4);
  g.setColor(g.theme.fg);
  g.setBgColor(g.theme.bg);

  if (settings.countdown) { // Display a countdown timer before scrolling
    g.setFontAlign(0, 0);
    countdownNum = 3;
    countdown();
    countdownInterval = setInterval(() => {
      if (countdownNum == 0) {
        clearInterval(countdownInterval);
        startScrolling();
      } else {
        countdown();
      }
    }, 1000);
  } else { // No countdown, so just scroll
    startScrolling();
  }
}

// Start the scroll animation
function startScrolling() {
  g.clear();
  g.setFontAlign(-1, 0); // Vertical align text

  x=g.getWidth(); // Start the text just off screen

  scrollInterval = setInterval(() => {
    g.clear();
    g.drawString(text, x, g.getHeight()/2);
    x=x-10;
    if (x<-g.stringWidth(text)) { // Loop the text
      x=g.getWidth();
    }
  }, settings.speed);
}

// Show countdown timer
function countdown() {
    g.clear();
    g.drawString(countdownNum, g.getWidth()/2, g.getHeight()/2);
    countdownNum--;
}

// Load keyboard and set text
function editText() {
  try {
    require("textinput").input({text:text}).then(result => {
      text = result;
      if (settings.rememberText) {
        setSetting('lastText', text);
      }
      layout.text.label = text ? text : 'Enter text...'; // Show prompt if text not set
      layout.text.col = text ? g.theme.fg2 : '#555'; // Grey text if prompt shown
      layout.setUI();
      layout.render();
      Bangle.drawWidgets();
    });
  } catch (error) {
    E.showAlert('Please install a keyboard app').then(() => {
      layout.setUI();
      layout.render();
    });
  }
}

// Save setting key
function setSetting(key,value) {
  settings[key] = value;
  require('Storage').writeJSON(SETTINGS, settings);
}

// Helper method which uses int-based menu item for set of string values and their labels
function stringItems(key, startvalue, values, labels) {
  return {
    value: (startvalue === undefined ? 0 : values.indexOf(startvalue)),
    format: v => labels[v],
    min: 0,
    max: values.length - 1,
    wrap: true,
    step: 1,
    onchange: v => {
      setSetting(key,values[v]);
    }
  };
}

// Helper method which breaks string set settings down to local settings object
function stringInSettings(name, values, labels) {
  return stringItems(name,settings[name], values, labels);
}

// Settings menu
function showSettings() {
  E.showMenu({
    '' : { 'title' : 'Settings' },
    '< Back' : () => {
      g.clearRect(Bangle.appRect);
      layout.setUI();
      layout.render();
    },
    'Rotate': stringInSettings('rotate', [0, 1, 2, 3], [0, 90, 180, 270]),
    'Speed': stringInSettings('speed', [10, 50, 80], ['Fast', 'Medium', 'Slow']),
    'Max bright': {
      value: !!settings.maxBright,
      onchange: v => {
        setSetting('maxBright', v);
      },
    },
    "Don't dim": {
      value: !!settings.doNotDim,
      onchange: v => {
        setSetting('doNotDim', v);
      },
    },
    'Countdown': {
      value: !!settings.countdown,
      onchange: v => {
        setSetting('countdown', v);
      },
    },
    'Remember text': {
      value: !!settings.rememberText,
      onchange: v => {
        setSetting('rememberText', v);
        if (v) {
          setSetting('lastText', text);
        } else {
          setSetting('lastText', '');
        }
      },
    }
  });
}

// Initial layout render
g.clear();
Bangle.drawWidgets();
layout.render();


