#include <EEPROM.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>

#define UI unsigned int
#define DHT_TYPE DHT22
#define DHT_PIN 25
#define BUTTON_PIN 4
#define EEPROM_ADDR_MIN 0
#define EEPROM_ADDR_MAX sizeof(float)

UI prev = 0, lastUpdate = 0, lastPress = 0;
float temp, tMin, tMax;
bool celsius = true;

byte grau[8] = {0b00110, 0b01001, 0b01001, 0b00110,
                0b00000, 0b00000, 0b00000, 0b00000};
byte setaBaixo[8] = {0b00000, 0b00100, 0b00100, 0b00100,
                     0b10101, 0b01110, 0b00100, 0b00000};
byte setaCima[8] = {0b00000, 0b00100, 0b01110, 0b10101,
                   0b00100, 0b00100, 0b00100, 0b00000};

LiquidCrystal_I2C lcd(0x27,16,2);
DHT dht(DHT_PIN, DHT_TYPE);

void setup() {
  Serial.begin(9600);
  pinMode(BUTTON_PIN, INPUT);
  lcd.init();
  lcd.backlight();
  lcd.createChar(0, grau);
  lcd.createChar(1, setaBaixo);
  lcd.createChar(2, setaCima);
  dht.begin();
  check();
}

void check() {
  EEPROM.get(EEPROM_ADDR_MIN, tMin);
  EEPROM.get(EEPROM_ADDR_MAX, tMax);
  if (tMin < 0 || tMax < 0 || tMin > 100 || tMax > 100) {
    temp = dht.readTemperature();
    updateMin();
    updateMax();
  }

}

void loop() {
  UI now = millis();
  if (now - prev > 100) { // Screen rate ±10FPS
    printScreen();
    prev = now;
  }
  if (now - lastUpdate > 1000) { // DHT update rate?
    temp = dht.readTemperature();
    if (temp < tMin) updateMin();
    if (temp > tMax) updateMax();
    lastUpdate = now;
  }
  if (digitalRead(BUTTON_PIN) == HIGH) {
    while (digitalRead(BUTTON_PIN) == HIGH) {
      UI pressed = millis();
      if ((pressed - now) > 2000) {
        updateMin();
        updateMax();
        break;
      }
    }
    if (now - lastPress > 500) celsius = !celsius;
    lastPress = now;
  }
}
  
void printScreen() {
  lcd.clear();
  if (celsius) {
    lcd.setCursor(2,0);
    lcd.print("Temp.: " + String(temp, 1) + "\x08" + "C");
    lcd.setCursor(0,1);
  	lcd.print("\x01" + String(tMin, 1) + "\x08" + "C");
    lcd.setCursor(8,1);
    lcd.print("\x02" + String(tMax, 1) + "\x08" + "C");
  } else {
    lcd.setCursor(2,0);
    lcd.print("Temp.: " + String((int)fahr(temp)) + "F");
    lcd.setCursor(0,1);
  	lcd.print("\x01" + String((int)fahr(tMin)) + "F");
    lcd.setCursor(8,1);
    lcd.print("\x02" + String((int)fahr(tMax)) + "F");
  }
}

void updateMin() {
  tMin = temp;
  EEPROM.write(EEPROM_ADDR_MIN, tMin);
}

void updateMax() {
  tMax = temp;
  EEPROM.write(EEPROM_ADDR_MAX, tMax);
}

float fahr(float c) {
  return (float) 9/5 * c + 32.0;
}