class BanglejsApp {
  constructor() {
    this.maxSamples = 16;
    this.target = {
      xMin: Math.floor(0.1 * g.getWidth()),
      xMax: Math.floor(0.9 * g.getWidth()),
      yMin: Math.floor(0.1 * g.getHeight()),
      yMax: Math.floor(0.9 * g.getHeight()),
    };
    this.x = 0;
    this.y = 0;
    this.step = 0;
    this.settings = {
      xoffset: [0],
      yoffset: [0],
      xMaxActual: [this.target.xMax],
      yMaxActual: [this.target.yMax],
      };
  }

  load_settings() {
    let settings = require('Storage').readJSON('calibration.json', true) || {active: false};

    console.log('loaded settings:');
    console.log(settings);

    return settings;
  }

  getMedian(array){
    array.sort();
    let i = Math.floor(array.length/2);
    if ( array.length % 2 && array.length > 1 ){
        return (array[i]+array[i+1])/2;
    } else {
        return array[i];
    }
  }

  getMedianSettings(){
    let medianSettings = {
      xoffset: this.getMedian(this.settings.xoffset),
      yoffset: this.getMedian(this.settings.yoffset)
    };

    medianSettings.xscale = this.target.xMax / (medianSettings.xoffset + this.getMedian(this.settings.xMaxActual));
    medianSettings.yscale = this.target.yMax / (medianSettings.yoffset + this.getMedian(this.settings.yMaxActual));
    return medianSettings;
  }

  save_settings() {
    let settingsToSave =  this.getMedianSettings();
    settingsToSave.active = true;
    settingsToSave.reload = false;
    require('Storage').writeJSON('calibration.json', settingsToSave);

    console.log('saved settings:', settingsToSave);
  }

  explain() {
    /*
    * TODO:
    * Present how to use the application
    *
    */
  }

  drawTarget() {
    switch (this.step){
      case 0:
        this.x = this.target.xMin;
        this.y = this.target.yMin;
        break;
      case 1:
        this.x = this.target.xMax;
        this.y = this.target.yMin;
        break;
      case 2:
        this.x = this.target.xMin;
        this.y = this.target.yMax;
        break;
      case 3:
        this.x = this.target.xMax;
        this.y = this.target.yMax;
        break;
    }

    g.clearRect(0, 0, g.getWidth(), g.getHeight());
    g.setColor(g.theme.fg);
    g.drawLine(this.x, this.y - 5, this.x, this.y + 5);
    g.drawLine(this.x - 5, this.y, this.x + 5, this.y);
    g.setFont('Vector', 10);
    let medianSettings = this.getMedianSettings();
    g.drawString('current offset: ' + medianSettings.xoffset.toFixed(3) + ', ' + medianSettings.yoffset.toFixed(3), 2, (g.getHeight()/2)-6);
    g.drawString('current scale: ' + medianSettings.xscale.toFixed(3) + ', ' + medianSettings.yscale.toFixed(3), 2, (g.getHeight()/2)+6);
  }

  setOffset(xy) {
    switch (this.step){
      case 0:
        this.settings.xoffset.push(this.x - xy.x);
        this.settings.yoffset.push(this.y - xy.y);
        break;
      case 1:
        this.settings.xMaxActual.push(xy.x);
        this.settings.yoffset.push(this.y - xy.y);
        break;
      case 2:
        this.settings.xoffset.push(this.x - xy.x);
        this.settings.yMaxActual.push(xy.y);
        break;
      case 3:
        this.settings.xMaxActual.push(xy.x);
        this.settings.yMaxActual.push(xy.y);
        break;
    }

    for (let c in this.settings){
      if (this.settings[c].length > this.maxSamples) this.settings[c] = this.settings[c].slice(1, this.maxSamples);
    }
  }

  nextStep() {
    this.step++;
    if ( this.step == 4 ) this.step = 0;
  }
}


E.srand(Date.now());

const calibration = new BanglejsApp();
calibration.load_settings();
Bangle.disableCalibration = true;

function touchHandler (btn, xy){
  if (xy) calibration.setOffset(xy);
  calibration.nextStep();
  calibration.drawTarget();
}

let modes = {
  mode  : 'custom',
  btn   : function(n) {
    calibration.save_settings(this.settings);
    load();
  },
  touch : touchHandler,
};
Bangle.setUI(modes);
calibration.drawTarget();
