/*
 * display.c
 *
 *  Created on: May 31, 2017
 *      Author: wn
 */


#include <hmi.h>
#include "stm32f1xx_hal.h"
#include "alarm.h"
#include <PontCoopScheduler.h>
#include "oled.h"
#include "eeprom.h"



const uint32_t STORAGE_MAGIC = 0xaffe000a;




volatile tDisplay display = {
    .toggle = 0, .setModeTemperature = 0, .setModeTime = 0,
    .timerState = IDLE,
    .toggleModeState = 1,
    .targetTemperature = 80, .currentTemperature = 75,
    .targetTime = 120, .currentTime = 0,
    .overrunTime = 0
};

typedef struct {
  uint32_t magic;
  uint32_t savedTemperature;
  uint32_t savedTime;
} tStorage;

tStorage storage;

void updateDisplay(void *handle) {
  tDisplay *lDisplay = (tDisplay*) handle;
  lDisplay->toggle ^= 0x01;
  char buf[32];

  sprintf(buf, "ThermometerTeaTimer");
  LED_P6x8Str(0, 0, buf);

  if (lDisplay->setModeTemperature && lDisplay->toggle) {
    sprintf(buf, "        %3d'C", lDisplay->currentTemperature);
  } else {
    sprintf(buf, "%3d'C   %3d'C", lDisplay->targetTemperature, lDisplay->currentTemperature);
  }
  LED_P8x16Str(0, 2, buf);

  if (lDisplay->setModeTime && lDisplay->toggle) {
    sprintf(buf, "        %3ds", lDisplay->currentTime);
  } else {
    sprintf(buf, "%3ds    %3ds", lDisplay->targetTime, lDisplay->currentTime);
  }
  LED_P8x16Str(0, 4, buf);

  sprintf(buf, "      %5ds", lDisplay->overrunTime);
//  static uint32_t h = 0;
//  static uint32_t c = 0;
//  uint32_t i = HAL_GetTick();
//  sprintf(buf, "%d %d %d", c, i, i-h);
//  h = i;
//  c++;
  LED_P8x16Str(0, 6, buf);
}


void hmiInit() {
  eepromRead(STORAGE_ADDRESS, &storage, sizeof(storage));
  if (storage.magic == STORAGE_MAGIC) {
    display.targetTemperature = storage.savedTemperature;
    display.targetTime = storage.savedTime;
  } else {
    storage.magic = STORAGE_MAGIC;
    storage.savedTemperature = 80;
    storage.savedTime = 90;
    eepromWrite(STORAGE_ADDRESS, &storage, sizeof(storage));

//    eepromRead(STORAGE_ADDRESS, &storage, sizeof(storage));
    display.targetTemperature = storage.savedTemperature;
    display.targetTime = storage.savedTime;
  }

  schAdd(updateDisplay, &display, 0, 250);
}

void clearSetMode(void *handle) {
  tDisplay *lDisplay = (tDisplay*) handle;
  lDisplay->setModeTemperature = 0;
  lDisplay->setModeTime = 0;
  lDisplay->toggleModeState = 1;
}

static void disableSetModeTimer() {
  schDel(clearSetMode, (void*)&display);
}

static void reEnableSetModeTimer() {
  schDel(clearSetMode, (void*)&display);
  schAdd(clearSetMode, (void*)&display, 10000, 0);
}

static void toggleSetMode() {
  switch (display.toggleModeState) {
  default:
  case 0:
    disableSetModeTimer();
    display.setModeTemperature = 0;
    display.setModeTime = 0;
    display.toggleModeState = 1;
    break;
  case 1:
    reEnableSetModeTimer();
    display.setModeTemperature = 1;
    display.setModeTime = 0;
    display.toggleModeState = 2;
    break;
  case 2:
    reEnableSetModeTimer();
    display.setModeTemperature = 0;
    display.setModeTime = 1;
    display.toggleModeState = 0;
    break;
  }
}

void displayIncValue() {
  if (display.setModeTemperature == 1) {
    reEnableSetModeTimer();
    if (display.targetTemperature < 100) {
      display.targetTemperature++;
      storage.savedTemperature = display.targetTemperature;
      eepromWrite(STORAGE_ADDRESS, &storage, sizeof(storage));
    }
  }
  if (display.setModeTime == 1) {
    reEnableSetModeTimer();
    if (display.targetTime < 999) {
      display.targetTime += 10;
      storage.savedTime = display.targetTime;
      eepromWrite(STORAGE_ADDRESS, &storage, sizeof(storage));
    }
  }
}

void displayDecValue() {
  if (display.setModeTemperature == 1) {
    reEnableSetModeTimer();
    if (display.targetTemperature > 0) {
      display.targetTemperature--;
      storage.savedTemperature = display.targetTemperature;
      eepromWrite(STORAGE_ADDRESS, &storage, sizeof(storage));
    }
  }
  if (display.setModeTime == 1) {
    reEnableSetModeTimer();
    if (display.targetTime >= 10) {
      display.targetTime -= 10;
      storage.savedTime = display.targetTime;
      eepromWrite(STORAGE_ADDRESS, &storage, sizeof(storage));
    }
  }
}

void buttonShort() {
  if (display.setModeTemperature == 1 || display.setModeTime == 1) {
    toggleSetMode();
  } else if (display.timerState == IDLE) {
    startTimer();
  } else if (display.timerState == RUNNING || display.timerState == OVERRUN) {
    stopTimer();
    disableAlarm();
  }
}

void buttonLong() {
  if (display.timerState == IDLE) {
    toggleSetMode();
  }
}
