#include <LiquidCrystal.h> //library initialize
#define stepPin 2
#define dirPin 5

LiquidCrystal lcd(13, 12, 11, 10, 9, 8); // initialize pins and variables
int startButton = 7;
int hours;
int minutes;
int seconds;
int note;
const int buzzer = 3;  //buzzer to arduino pin 9
float distance;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(startButton, INPUT_PULLUP); //button input
  lcd.begin(16, 2); //initialize LCD screen position
  lcd.clear();
  pinMode(buzzer, OUTPUT);  // Set buzzer - pin 9 as an output
  pinMode(stepPin, OUTPUT); // Set stepper pin as an output
  pinMode(dirPin, OUTPUT); // Set direction pin as an output
}

void loop() {
  // put your main code here, to run repeatedly:
  lcd.setCursor(0, 0);
  lcd.print("Set Alarm Time"); //print on lcd screen

  if (digitalRead(startButton) == LOW) { //when the alarm set button is pressed
    lcd.clear(); //clear the screen 
    int start = millis() + 10000; // add time to alarm
    delay(1000);
    while (digitalRead(startButton) == HIGH) { // count down from set time to zero while the button isnt pressed again
      int now = (start - millis()) / 1000;
      converttime(hours, minutes, seconds, now); //jump to different functions to convert time from milliseconds to hours minutes and seconds
      printtime(hours, minutes, seconds); // print the current time on the lcd screen
      delay(100);
      if (now == 0) break; //when the timer ends, break the loop
    }
    lcd.clear(); //clear the screen
    lcd.setCursor(0, 0);
    lcd.print("WAKE UP"); //tell user to wake up
    raiseBlinds(); //jump to function to raise blinds
    while (digitalRead(startButton) == HIGH) { //while the button isnt pressed, start annoying the sleeper with the alarm sound

      for (note = 440; note >= 100; note = note - 1) { //start at a high note and oscilate to low back to high to provide some fun to the alarm sound :D
        buzz();
        if (digitalRead(startButton) == LOW) break; //if the button is pressed break the loop and stop the loops
      }
      for (note = 100; note <= 440; note++) {
        buzz();
        if (digitalRead(startButton) == LOW) break;
      }
      noTone(buzzer); //turn off the buzzer
    }
    delay(5000);
  }
}

void converttime(int &hc, int &mc, int &sc, unsigned long int nowcs) {
  // This function converts time in ms to hours minutes and seconds
  Serial.println(nowcs);
  hc = floor(nowcs / 3600.0);
  mc = floor((nowcs - hc * 3600.0) / 60.0);
  sc = nowcs - hc * 3600.0 - mc * 60.0;
}
void printtime(int hc, int mc, int sc) {
  // This function prints the time as 00:00:00
  lcd.setCursor(0, 0);
  lcd.print("TIME:");
  if (hc >= 10) {
    lcd.print(hc);
  } else {
    lcd.print("0");
    lcd.print(hc);
  }
  lcd.print(":");
  if (mc >= 10) {
    lcd.print(mc);
  } else {
    lcd.print("0");
    lcd.print(mc);
  }
  lcd.print(":");
  if (sc >= 10) {
    lcd.print(sc);
  } else {
    lcd.print("0");
    lcd.print(sc);
  }
  lcd.print(" ");
}

void raiseBlinds() { //raise blinds function
  digitalWrite(dirPin, HIGH); //set direction of travel for the motor
  for (int x = 0; x < 2000; x++) { //function to incrementally step the motor in 10 loops to raise the blinds
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(700);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(700);
  }
}

void buzz() { //buzzer function
  tone(buzzer, note);  // Send 1KHz sound signal...
  delay(10);           // ...for 1 sec
}