#define oneSecond 1000
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128     // OLED display width, in pixels
#define SCREEN_HEIGHT 64     // OLED display height, in pixels
#define OLED_RESET -1        // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C  ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

const int rest = A0;
const int ten_Min = 3;
const int twenty_Min = A2;
const int thirty_Min = A3;
const int forty_Min = 2;
const int fifty_Min = 5;
const int Hour = 6;
const int buzz = 4;
const int relay = 8;
int hrs = 0;
int Min = 0;
int sec = 0;

bool RUN = true;
bool min_flag = true;
bool hrs_flag = true;
void timer(void);
unsigned long tNow;
void setup() {
  Serial.begin(115200);
  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
  }

  display.clearDisplay();

  display.setTextSize(2);  // Draw 2X-scale text
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(10, 20);
  display.println(F("CO2inhale "));
  display.display();
  delay(2000);

  display.clearDisplay();
  pinMode(rest, INPUT_PULLUP);
  pinMode(ten_Min, INPUT_PULLUP);
  pinMode(twenty_Min, INPUT_PULLUP);
  pinMode(thirty_Min, INPUT_PULLUP);
  pinMode(forty_Min, INPUT_PULLUP);
  pinMode(fifty_Min, INPUT_PULLUP);
  pinMode(Hour, INPUT_PULLUP);

  pinMode(buzz, OUTPUT);
  pinMode(relay, OUTPUT);
  digitalWrite(relay, LOW);
  digitalWrite(buzz, LOW);

  outEndTone();
}

void loop() {
  dispSetTime();
  if (digitalRead(ten_Min) == LOW) {
    Min = 5; sec = 0;
    delay(100);
    timer();
  } else if (digitalRead(twenty_Min) == LOW) {
    Min = 10; sec = 0;
    delay(100);
    timer();
  } else if (digitalRead(thirty_Min) == LOW) {
    Min = 15; sec = 0;
    delay(100);
    timer();
  } else if (digitalRead(forty_Min) == LOW) {
    Min = 20; sec = 0;
    delay(100);
    timer();
  } else if (digitalRead(fifty_Min) == LOW) {
    Min = 25; sec = 0;
    delay(100);
    timer();
  } else if (digitalRead(Hour) == LOW) {
    Min = 30; sec = 0;
    delay(100);
    timer();
  }
}

void dispSetTime() {
  display.clearDisplay();
  display.setTextSize(2);  // Draw 2X-scale text
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(15, 20);
  display.println(F("Set Time"));
  display.display();

}

void timer(void) {
  display.clearDisplay();
  RUN = true;
  tNow = millis();
  while (RUN) {
    digitalWrite(relay, HIGH);
    dispTime();

    if((millis()-tNow)>=oneSecond){
      tNow = millis();
      updateTime();
    }   
    

    if (Min == 0 && sec == 0) {
      digitalWrite(relay, LOW);
      display.clearDisplay();
      display.setTextSize(2);  // Draw 2X-scale text
      display.setTextColor(SSD1306_WHITE);
      display.setCursor(1, 0);
      display.println(F("Time Out"));
      display.display();
      delay(200);
      RUN = false;
      outEndTone();
    }

    if (digitalRead(rest) == LOW) {
      digitalWrite(relay, LOW);
      display.clearDisplay();
      display.setTextSize(2);  // Draw 2X-scale text
      display.setTextColor(SSD1306_WHITE);
      display.setCursor(1, 0);
      display.println(F("Resetting"));
      display.display();
      delay(1000);
      RUN = false;
    }

  }
}

void dispTime() {
  display.clearDisplay();
  display.setTextSize(4);  // Draw 2X-scale text
  display.setTextColor(SSD1306_WHITE);
  if(Min>=10)
    display.setCursor(5, 20);
  else
    display.setCursor(15, 20);

  display.print(Min);

  display.print(":");
  display.setTextSize(4);  // Draw 2X-scale text
  display.setTextColor(SSD1306_WHITE);

  if (sec <= 9)display.print("0");
  display.print(sec);
  display.display();
}

void updateTime(){
  sec = sec - 1;   
    if (sec == -1) {
      if(Min !=0){
      sec = 59;
      Min = Min - 1;
      }
      else{
        sec = 0;
        Min = 0;
        digitalWrite(relay,LOW);
        dispTime();
        delay(oneSecond);
      }
    }   
}
void outEndTone() {
  tone(buzz, 440, 100);
  delay(200);
  tone(buzz, 440, 100);
  delay(200);
  tone(buzz, 440, 100);
  delay(200);
  tone(buzz, 440, 1000);
  delay(1000);
}

//--------------(c) Electronics project hub -----------//