/*
: Project:Alarm Clock
: Author: Natã Souza (https://hackaday.io/hacker/524319-nat-souza)
: Date: 02/06/2020
: https://hackaday.io/project/169835-arduino-alarm-clock
*/

#include "LiquidCrystal.h"
#include "Wire.h"
#include "RTClib.h"

RTC_DS1307 RTC;
LiquidCrystal lcd (12, 11, 5, 4, 3, 2);

//Datetime t;

byte term [8] =  //creat a termomether icon
{
  B00101, 
  B01010, 
  B01010, 
  B01010, 
  B01010, 
  B11101, 
  B11111, 
  B01110
};
byte rel [8] = //creat a clock icon
{
  B01110, 
  B10001, 
  B10101, 
  B10101, 
  B10101, 
  B10011, 
  B10001, 
  B01110
 };

const int buzz = 6;
const int relay = 7;
const int b1 = 8;
const int b2 = 10;
const int b3 = 9;

int menu = 0 ;
int alarm = 0;
int alarmOn = 0;
int alarmH = 0;
int alarmM = 0;

int hora;
int minuto;
int segundo;
int dia;
int mes;
int ano;
int diasemana;

void setup()
{
  Wire.begin();
  lcd.begin(16, 2);
  RTC.begin();
  
  pinMode(buzz, OUTPUT);
  pinMode(relay, OUTPUT);
  pinMode(b1, INPUT);
  pinMode(b2, INPUT);
  pinMode(b2, INPUT);

  lcd.createChar(0, term);
  lcd.createChar(1, rel);
  }

//---------------------------------------------------------------------

void loop()
{
  DateTime t = RTC.now();

  hora = t.hour();
  minuto = t.minute();
  segundo = t.second();
  dia = t.day();
  mes = t.month();
  ano = t.year() - 2000;
  diasemana = t.dayOfTheWeek();
  
//---------------------------------------------------------------------

//MENU NAVEGATION:
//I wanted to increase a menu systen, so you can change the menu utilizing the botton 1
  if (digitalRead(b1) == HIGH)
  {
    lcd.clear();
    menu ++;
    if(menu == 2)
    {
      menu = 0;
    }
    delay(100);
  }

//----------------------------------------------------------------------------------------

//MENU 1: CLOCK MODE
  if (menu == 0)
  {
    lcd.noBlink();
    lcd.setCursor(0,0);
    givedow();
    lcd.setCursor(0, 1);
    givetime();
    lcd.setCursor(11, 1);
    givestate();
  }

//---------------------------------------------------------------------------------

//MENU 2: ALARM ADJUST
  if (menu == 1)
  {
    lcd.setCursor(0, 0);
    lcd.print("Alarm adjust:");
    lcd.setCursor(0, 1);
    giveATime();
    lcd.setCursor(11, 1);
    givestate();
    if (digitalRead(b2) == HIGH)
    {
      alarmM++;
      delay(150);
      if (alarmM > 59)
      {
        alarmM = 0;    
      }
    }
    if (digitalRead(b3) == HIGH)
    {
      alarmH++;
      delay(150);
      if (alarmH > 23)
      {
        alarmH = 0;
      }
    }
    if (digitalRead(b2) == HIGH && digitalRead(b3) == HIGH)
    {
      alarm++;
      lcd.setCursor(12, 1);
      lcd.print("    ");
      delay(300);
      if (alarm == 2)
      {
        alarm = 0;
      }
    }
  }

//----------------------------------------------------------------------------------------------

//ALARM FUNCTION:
  if (alarm == 1 && alarmH == hora &&  (alarmM - 1) == minuto)// I needed to add this function so that the alarm clock does not reset each time the alarm goes off.
  {
    alarmOn = 1;
  }
  if (alarm == 1 && alarmOn == 1 && alarmH == hora &&  alarmM == minuto)// this lines compare the RTC time with the set time and, if they match, the alarm will turn on
  {
    buzzer();
    if (digitalRead(b3) == HIGH)
    {
      alarmOn = 0;
    }
  }

//----------------------------------------------------------------------------------------------
}

//----------------------------------------------------------------------------------------------

//AUXILIARY FUNCTIONS
void givetime()
{
    if (hora < 10){
      lcd.print("0");
    }
    lcd.print(hora);
    lcd.print(":");
    if (minuto < 10){
      lcd.print("0");
    }
    lcd.print(minuto);
    lcd.print(":");
    if (segundo < 10){
      lcd.print("0");
    }
    lcd.print(segundo);
}

void givedow()
{
    if (diasemana == 1)
    {
      lcd.print("SUNDAY");
    }
    if (diasemana == 2)
    {
      lcd.print("MONDAY");
    }
    if (diasemana == 3)
    {
      lcd.print("TUESDAY");
    }
    if (diasemana == 4)
    {
      lcd.print("WEDNESDAY");
    }
    if (diasemana == 5)
    {
      lcd.print("THURSDAY");
    }
    if (diasemana == 6)
    {
      lcd.print("FRIDAY");
    }
    if (diasemana == 7)
    {
      lcd.print("SATURDAY");
    }
    lcd.print(" ");
    if (dia < 10){
      lcd.print("0");
    }
    lcd.print(dia);
    lcd.print("/");
    if (mes < 10){
      lcd.print("0");
    }
    lcd.print(mes);
    lcd.print("/");
    lcd.print(ano);
}

void givestate()
{
  if (alarm == 0)
  {
    lcd.write(1);
    lcd.print(":OFF");
  }
  if (alarm == 1)
  {
    lcd.write(1);
    lcd.print(":ON");
  }
}

void giveATime()
{
  if (alarmH < 10){
    lcd.print("0");
  }
  lcd.print(alarmH);
  lcd.print(":");
  if (alarmM < 10){
    lcd.print("0");
  }
  lcd.print(alarmM);
  lcd.print(":");
  lcd.print("00");
}

void buzzer()
{
  digitalWrite(buzz, HIGH);
  delay(450);
  digitalWrite(buzz, LOW);
  delay(450);
}
GND5VSDASCLSQWRTCDS1307+