#include <Wire.h>
#include <I2C_RTC.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
static DS3231 RTC;
LiquidCrystal_I2C lcd(0x27, 16, 02);
#define rain_sense A0
#define set_hr_up 2
#define set_hr_down 3
#define select_preset 4
#define relay 5
#define buzzer 6
//for button debounce
int debounceDelay = 50;
int buttonState1 = HIGH;
int lastButtonState1 = HIGH;
unsigned long lastDebounceTime1 = 0;
int buttonState2 = HIGH;
int lastButtonState2 = HIGH;
unsigned long lastDebounceTime2 = 0;
int buttonState3 = HIGH;
int lastButtonState3 = HIGH;
unsigned long lastDebounceTime3 = 0;
int hr_to_run1 = 12; //time to run
int hr_to_run2 = 1;
int selected = 3; //function select 1 - 3
bool watered = false;
void setup()
{
  Serial.begin(9600);
  RTC.begin();
  lcd.begin(16, 02);
  lcd.backlight();
  pinMode(set_hr_up, INPUT_PULLUP);
  pinMode(set_hr_down, INPUT_PULLUP);
  pinMode(select_preset, INPUT_PULLUP);
  pinMode(relay, OUTPUT);
  pinMode(buzzer, OUTPUT);
  // RTC.setDay(22);
  // RTC.setMonth(5);
  // RTC.setYear(2020);
  // RTC.setHours(18);
  // RTC.setMinutes(47);
  // RTC.setSeconds(56);
  //RTC.setDate(22,07,29);
  //RTC.setTime(22,10,20);
  hr_to_run1 = readEEPROM(1);
  hr_to_run2 = readEEPROM(2);
  if (hr_to_run1 == 255 || hr_to_run2 == 255) {
    writeEEPROM(1, 12);
    writeEEPROM(2, 12);
    hr_to_run1 = readEEPROM(1);
    hr_to_run2 = readEEPROM(2);
  }
  lcd.clear();
}
void loop()
{
  int water_level = analogRead(rain_sense);
  int hrs = RTC.getHours();
  int mnt = RTC.getMinutes();
  lcd.setCursor(11, 0);
  lcd.print(hrs);
  lcd.print(":");
  lcd.print(mnt);
  lcd.setCursor(0, 0);
  lcd.print("Run1: ");
  lcd.print(hr_to_run1);
  lcd.print(" ");
  lcd.setCursor(0, 1);
  lcd.print("Run2: ");
  lcd.print(hr_to_run2);
  lcd.print(" ");
  int rain_s = analogRead(rain_sense);
  lcd.setCursor(11, 1);
  if (rain_s > 500) {
    lcd.print("Sunny");
    if (hrs == hr_to_run1 || hrs == hr_to_run2) {
      if (!watered && selected == 3) {
        Serial.println("watering");
        digitalWrite(relay, HIGH);
        tone(buzzer, 1000);
        delay(1000);
        noTone(buzzer);
        delay(4000);
        digitalWrite(relay, LOW);
        watered = true;
      }
    } else {
      watered = false;
    }
  }else{
    lcd.print("Rainy");
  }
  
  int select = digitalRead(select_preset);
  int hrs_b = digitalRead(set_hr_up);
  int mnt_b = digitalRead(set_hr_down);
  debounceButton(select, lastButtonState1, lastDebounceTime1, buttonState1, "select");
  debounceButton(hrs_b, lastButtonState2, lastDebounceTime2, buttonState2, "up");
  debounceButton(mnt_b, lastButtonState3, lastDebounceTime3, buttonState3, "down");
}
void debounceButton(int reading, int &lastButtonState, unsigned long &lastDebounceTime, int &buttonState, String func) {
  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }
  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading != buttonState) {
      buttonState = reading;
      if (buttonState == LOW) {
        if (func == "select") {
          tone(buzzer, 2000);
          delay(100);
          noTone(buzzer);
          selected ++;
          selected = selected > 3 ? 1 : selected;
          if (selected == 1) {
            lcd.setCursor(9, 0);
            lcd.print("<");
            lcd.setCursor(9, 1);
            lcd.print(" ");
          } else if (selected == 2) {
            lcd.setCursor(9, 0);
            lcd.print(" ");
            lcd.setCursor(9, 1);
            lcd.print("<");
          } else if (selected == 3) {
            lcd.setCursor(9, 0);
            lcd.print(" ");
            lcd.setCursor(9, 1);
            lcd.print(" ");
            writeEEPROM(1, hr_to_run1);
            writeEEPROM(2, hr_to_run2);
            lcd.setCursor(10, 1);
            lcd.print("Save!");
            tone(buzzer, 1500);
            delay(100);
            tone(buzzer, 1000);
            delay(100);
            tone(buzzer, 500);
            delay(100);
            noTone(buzzer);
            delay(800);
            lcd.print("     ");
            lcd.clear();
          }
        }
        if (selected < 3) {
          if (func == "up") {
            tone(buzzer, 2000);
            delay(100);
            noTone(buzzer);
            if (selected == 1) {
              hr_to_run1 ++;
              hr_to_run1 = hr_to_run1 > 24 ? 1 : hr_to_run1;
            } else if (selected == 2) {
              hr_to_run2 ++;
              hr_to_run2 = hr_to_run2 > 24 ? 1 : hr_to_run2;
            }
          }
          if (func == "down") {
            tone(buzzer, 2000);
            delay(100);
            noTone(buzzer);
            if (selected == 1) {
              hr_to_run1 --;
              hr_to_run1 = hr_to_run1 < 1 ? 24 : hr_to_run1;
            } else if (selected == 2) {
              hr_to_run2 --;
              hr_to_run2 = hr_to_run2 < 1 ? 24 : hr_to_run2;
            }
          }
        }
      }
    }
  }
  lastButtonState = reading;
}
void writeEEPROM(int adrs, int data) {
  EEPROM.write(adrs, data);
  Serial.println("Data written to EEPROM");
}
int readEEPROM(int adrs) {
  return EEPROM.read(adrs);
}